RSA使用JSEncrypt加密并使用BouncyCastle(Java)解密

时间:2017-04-06 13:31:25

标签: java typescript bouncycastle jsencrypt

这可能与this answered question重复,但我似乎无法获得相同的结果。希望在这里有一些指导。

JSEncrypt(客户端)

let encrypt = new Encrypt.JSEncrypt();
encrypt.setPublicKey(this.publicKey);  // retrieved from server
encrypt.encrypt(password);

BouncyCastle(服务器) - RSA密钥生成

KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(1024);
KeyPair pair = generator.generateKeyPair();
PublicKey pubKey = pair.getPublic();
PrivateKey privKey = pair.getPrivate();

// returned to client
String publicKeyStr = new String(Base64.encodeBase64(pubKey.getEncoded()));
String privateKeyStr = new String(Base64.encodeBase64(privKey.getEncoded()));

BouncyCastle(服务器) - 解密

Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// org.apache.commons.codec.binary.Hex

byte[] cipherText = cipher.doFinal(Hex.decodeHex(encrypted.toCharArray()));
decrypted = new String(cipherText, BaseConstant.ENC_UTF8);

错误

  

org.apache.commons.codec.DecoderException:索引0处的非法十六进制字符I           在org.apache.commons.codec.binary.Hex.toDigit(Hex.java:178)           在org.apache.commons.codec.binary.Hex.decodeHex(Hex.java:89)

我注意到的一件事是JSEncrypt的加密文本长度为172,而服务器端的加密产生了256。

使用RSA / None / PKCS1Padding提到了已回答的问题,我已经设置过了。我还能错过什么?

2 个答案:

答案 0 :(得分:2)

The error occurs in Hex.decodeHex() method, which means that your data is not a Hex encoded string.

JSEncrypt.encrypt() method returns the encrypted data in Base64 (instead of Hex string). In order to decrypt it, you must decode it from base64 format.

So instead of:

byte[] cipherText = cipher.doFinal(Hex.decodeHex(encrypted.toCharArray()));

Do this:

byte[] cipherText = cipher.doFinal(Base64.decodeBase64(encrypted.toCharArray()));

答案 1 :(得分:0)

您也可以仅从客户端解决此问题。请参见下面的代码:

let encrypt = new Encrypt.JSEncrypt(); 
encrypt.setPublicKey(this.publicKey);
encrypt.getKey().encrypt(password);

只需在getKey()之后添加encrypt。它为我工作!我使用这种方法将密码加密为十六进制字符串。