RSA私钥解密操作
- 一、背景
- 二、操作
- 三、常见问题
- 3.1 invalid key format
- 3.2 解密的数据太长
- 3.3 Decryption error
一、背景
项目数据库中存放的敏感字段已使用rsa加密
的方式,将内容加密成密文存放,
现在需要在使用的时候,使用私钥进行解密。
二、操作
代码如下:
public class RsaUtil {
private static final int MAX_DECRYPT_BLOCK = 256;
/**
* 解密方法
* @param content 需解密内容
* @param privateKey 私钥
* @return
*/
public static String decryptByPrivateKey(String content,String privateKey) {
String decryptContent;
try {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
log.info("provider:{}",cipher.getProvider());
byte[] encryptedData = Base64.getDecoder().decode(content);
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;
}
out.close();
decryptContent = out.toString();
} catch (Exception e){
log.error("rsa解密内容:"+content+"失败",e);
throw new RsaException("rsa解密内容:"+content+"失败",e);
}
return decryptContent;
}
}
三、常见问题
3.1 invalid key format
错误信息如下:
Caused by: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:217)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)
原因:
私钥转成byte数组时没有使用base64解码
的方式:
3.2 解密的数据太长
参考文章:
https://blog.csdn.net/qq_42795685/article/details/107517196
错误信息如下:
IllegalBlockSizeException: Data must not be longer than 256 bytes
解决:
采用分段解密
的方式。具体请参考代码中分段解密注释的部分
3.3 Decryption error
参考文章:
-
https://blog.csdn.net/a1017680279/article/details/79061412?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-79061412-blog-71627949.235%5Ev38%5Epc_relevant_anti_vip_base&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-79061412-blog-71627949.235%5Ev38%5Epc_relevant_anti_vip_base&utm_relevant_index=1
-
https://juejin.cn/post/7182388540259450940
错误信息:
javax.crypto.BadPaddingException: Decryption error
原因:
代码中采取分段解密的方式时,配置的最大解密长度不正确
,即以上代码中的MAX_DECRYPT_BLOCK
变量配置长度有问题;
解决:
MAX_DECRYPT_BLOCK应等于密钥长度/8
(1byte=8bit),
“密钥长度”一般只是指模值的位长度。目前主流可选值:1024、2048、3072、4096,
我使用的密钥长度是2048,所以配置的最大解密长度应该是256。