一、原因:
实际使用RSA加解密算法通常有两种不同的方式,一种是使用对称密钥(比如 AES/ DES等加解密方法)加密数据,然后使用非对称密钥(RSA加解密密钥)加密对称密钥;另一种是直接使用非对称密钥加密数据。第一种方式安全性高,复杂度也高,不存在加密数据长度限制问题,第二种方式安全性差一些,复杂度低,但是存在加密数据限制问题(即使用非对称密钥加密数据时,一次加密的数据长度是(密钥长度/8-11))。
目前双方约定的方式为第二种方式,而对应于本次抛错的密钥,key长度为1024位,1024/8 - 11 = 117,所以一次加密内容不能超过117bytes。另一个密钥没有问题,因为key的长度为2048位, 2048 /8 - 11 = 245, 一次加密内容不能超过 245 bytes。而分段加密代码中用128为单位分段,从而使得一个密钥报错,另一个不报错。
二、解决:
/**
* RSA私钥解密
* str加密字符串
* privateKey私钥
* return明文
*/
public static String decryptByPrivateKey(String str, String privateKey) {
try {
//base64解码加密后的字符串
byte[] inputByte = org.apache.commons.codec.binary.Base64.decodeBase64(str.getBytes(CHATSET));
//base64编码的私钥
byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
//String outStr = new String(cipher.doFinal(inputByte));
//当长度过长的时候,需要分割后解密 256个字节
String outStr = new String(getMaxResultDecrypt(str, cipher));
return outStr;
} catch (Exception e) {
logger.info(e.getMessage(), e);
}
return null;
}
//长度过长分割解密
private static byte[] getMaxResultDecrypt(String str, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
byte[] inputArray = Base64.decodeBase64(str.getBytes("UTF-8"));
int inputLength = inputArray.length;
logger.info("inputLength: "+inputLength);
// 最大解密字节数,超出最大字节数需要分组加密
int MAX_ENCRYPT_BLOCK = 256;
// 标识
int offSet = 0;
byte[] resultBytes = {};
byte[] cache = {};
while (inputLength - offSet > 0) {
if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
offSet += MAX_ENCRYPT_BLOCK;
} else {
cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
offSet = inputLength;
}
resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
}
return resultBytes;
}
参考:Java使用RSA进行加密解密【完美版本】;Data must not be longer than 117 bytes【不报此错误】_superswang的博客-CSDN博客