我想使用带有公钥的RSA在javascript中加密一个小字符串,然后使用私钥在java服务器端代码中解密该字符串。
我在javascript中使用此代码: http://www-cs-students.stanford.edu/~tjw/jsbn/ 示例: http://www-cs-students.stanford.edu/~tjw/jsbn/rsa2.html
和java方面的代码: Encrypting string in javascript and decryption in java
两个代码都独立工作,但彼此不了解。今天需要解决这个问题,或者我愿意接受以这种方式工作的任何其他非对称算法。
答案 0 :(得分:3)
您正在使用Java端的原始加密和使用Java Card端的PKCS#1 v1.5填充的RSA加密。您应该尝试通过javax.crypto.Cipher.getInstance("RSA/None/PKCS1Padding")
使用Java RSA。如果存在,请不要忘记删除任何base 64编码。
答案 1 :(得分:3)
想要留下更多代的例子:)
首先,我们需要在java代码中生成密钥对
KeyPairGenerator kpg;
try {
kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
yourVariablePublic = kp.getPublic();
yourVariablePublic = kp.getPrivate();
} catch(NoSuchAlgorithmException e) {
}
现在让我们转到我们当前页面的java代码:
// receiving public key from where you store it
Key publicKey = YourCarrierClass.getYourVariablePublic();
KeyFactory fact;
// initializing public key variable
RSAPublicKeySpec pub = new RSAPublicKeySpec(BigInteger.ZERO, BigInteger.ZERO);
try {
fact = KeyFactory.getInstance("RSA");
pub = fact.getKeySpec(publicKey, RSAPublicKeySpec.class);
} catch(NoSuchAlgorithmException e1) {
} catch(InvalidKeySpecException e) {
}
// now you should pass Modulus string onto your html(jsp) in such way
String htmlUsedModulus = pub.getModulus().toString(16);
// send somehow this String to page, so javascript can use it
现在为javascript方面:
function sendPassword() {
var password = $('#passwordField').val();
var rsa = new RSAKey();
rsa.setPublic($('#keyModulus').text(), '10001');
var res = rsa.encrypt(password);
$('#ajaxSentPassword').val(res);
}
并在java代码中解密它:
Key privateKey = YourCarrierClass.getYourVariablePrivate();
Cipher cipher;
BigInteger passwordInt = new BigInteger(ajaxSentPassword, 16);
byte[] dectyptedText = new byte[1];
try {
cipher = javax.crypto.Cipher.getInstance("RSA/ECB/PKCS1Padding");
byte[] passwordBytes = passwordInt.toByteArray();
cipher.init(Cipher.DECRYPT_MODE, privateKey);
dectyptedText = cipher.doFinal(passwordBytes);
} catch(NoSuchAlgorithmException e) {
} catch(NoSuchPaddingException e) {
} catch(InvalidKeyException e) {
} catch(IllegalBlockSizeException e) {
} catch(BadPaddingException e) {
}
String passwordNew = new String(dectyptedText);
System.out.println("Password new " + passwordNew);
你走了,对不起,我不善于处理这些捕获条款。
=============================================== =====================
UPD: 关于这段代码,我在这里找到了一些问题。 首先,您可以更改
的算法javax.crypto.Cipher.getInstance("RSA/ECB/PKCS1Padding");
到:
javax.crypto.Cipher.getInstance("RSA");
但这不是必需的,它适用于两者。 现在真正的问题是关于这一行
byte[] passwordBytes = passwordInt.toByteArray();
这里当你从BigInteger生成字节数组时,它有时会在前面添加[0]作为signum(有时候不是!所以算法可以解密那个数组),所以字节数组大小可以是65/129/257,这是不能破译的通过算法,它抛出IllegalBlockSizeException。 Getting 1 byte extra in the modulus RSA Key and sometimes for exponents also问题中讨论了此问题。 最简单的解决方案是从数组中删除零:
byte[] byteArray = new byte[256];
BigInteger passwordInt = new BigInteger(password, 16);
if (passwordInt.toByteArray().length > 256) {
for (int i=1; i<257; i++) {
byteArray[i-1] = passwordInt.toByteArray()[i];
}
} else {
byteArray = passwordInt.toByteArray();
}