RSA Java encryption and Node.js decryption is not working
我有一个系统,要求使用javascript生成RSA密钥对,然后将公共密钥存储在服务器端的数据库中(作为字符串),然后使用Java的服务器端将使用存储的公共密钥对字符串进行加密密钥并将其发送到客户端,客户端将使用私钥解密字符串。
我在客户端浏览器上使用的是node-rsa的浏览版本。
首先在客户端,我生成一个密钥对并导出密钥,并将其存储为字符串
1 2 3 4 | var NodeRSA = require('node-rsa'); var key = new NodeRSA({b: 1024}); key.exportKey("pkcs8-private"); key.exportKey("pkcs8-public-pem"); |
导出的私钥存储在客户端,公共存储在服务器上
接下来,我使用java加密接收到的公共密钥的字符串,因此我将pkcs8公共密钥解析为Java PublicKey对象。
1 2 3 4 5 6 7 8 9 10 | String pubKey ="<Retrieved pkcs8 public key>"; pubKey = pubKey.replaceAll("(-+BEGIN PUBLIC KEY-+\ ?\ |-+END PUBLIC KEY-+\ ?\ ?)",""); byte[] keyBytes = Base64.decodeBase64(pubKey); X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); KeyFactory kf = KeyFactory.getInstance("RSA"); PublicKey pk = kf.generatePublic(spec); |
并用它加密文本
1 2 3 4 5 | byte[] cipherText; Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pk); cipherText = cipher.doFinal("Hello World!".getBytes()); return Base64.encodeBase64String(cipherText); |
效果很好,并向我返回了像这样的Base64编码的加密字符串
1 | WTS1J2f4w5icsUOCtulyHDaBmB5lN7D8mnj0QWMDBkUGiPHkM8nHVx9pd0MtbQAQNasQS2X8kisLMYyEMPasFZtDH0zX1e8lNYaW0xMKsg++ge87f+95nl+TmxDy6S1m7Ce/n0wXno+0MbSv8YsJtsUcAleyyfQX2bxqX8u7Gjs= |
然后我尝试在客户端解密它的字符串
首先,我将存储的密钥重新导入到node-rsa中
1 2 3 4 | var NodeRSA = require('node-rsa'); var key = new NodeRSA(); key.importKey("<exported private key string>","pkcs8-private"); key.importKey("<exported public key string>","pkcs8-public-pem"); |
然后我尝试解密Base64编码的加密字符串
1 | key.decrypt("<Base64 Encoded Encrypted>", 'utf-8'); |
这是发生问题的地方,javascript抛出此错误
Uncaught Error: Error during decryption (probably incorrect key). Original error: Error: Error decoding message, the lHash calculated from the label provided and the lHash in the encrypted data do not match.(…)
However i have tested that if i encrypt and decrypt the text just within javascript, it works just fine. This makes me think that it's some difference between the way i encrypted it at java and how it's done at javascript
有人可以指出我在这里犯的错误吗?
哦,我找到了解决方案。 加密方法有所不同。
我只需要用初始化
1 | Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); |
代替
1 | Cipher.getInstance("RSA"); |
匹配node-rsa