在做一个web安全登录的作业时,遇到前后端RSA加密问题。。
后端 java
生成RSA密钥对,privateKey,publicKey
后端RSA是从帖子上抄的:
(学习加密四spring boot 使用RSA+AES混合加密,前后端传递参数加解密)[https://blog.csdn.net/baidu_38990811/article/details/83540404]
**使用PKCS8规范**
// 后端部分代码 RSA
/**
* 生成密钥对(公钥和私钥)
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(INITIALIZE_LENGTH);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 私钥解密
* @param encryptedData 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
前端:vue+webpack
后端拿到传回的encrypted, 再解密时报错
javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:383)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:294)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2222)
at com.security.loginserver.Util.RSAUtils.decryptByPrivateKey(RSAUtils.java:126)
at com.security.loginserver.Util.RSAUtils.decryptDataOnJava(RSAUtils.java:285)
现象:同样的内容使用jsencrypt加密和后端RSA加密后,密文结构类似长度不一样
结果:jsencrypt加密后解密正常,后端RSA加密解密正常(后端直接使用的hutool),jsencrypt加密后的密文给后端解密失败了
解决办法:求解
有结果了吗?遇到同样问题,求解。
试一下这个:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] cipherText = cipher.doFinal(Base64.decodeBase64(encrypted.getBytes()));
String decrypted = new String(cipherText, "UTF-8");
System.out.println("解密后内容:" + decrypted);
privateKey 是后台生成的私钥
encrypted 是利用jsencrypt加密后的密文