解决java rsa的错误:javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
2023-09-14 09:07:25 时间
复现问题
之前在对接第三方连连支付的接口时,报出如下错误:
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:344)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at com.asymmetric.rsa.TestRSA.testDecrypt(TestRSA.java:82)
at com.asymmetric.rsa.TestRSA.main(TestRSA.java:33)
即非法字符长度
的问题。
分析问题
因为RSA加密算法的默认公私钥的字节长度是256字节,但我通过Linux生成的字节数为2048字节,显然超过的RSA默认的字节长度,如下代码:
/**
* 签名处理
*
* @param prikeyvalue:私钥
* @param sign_str:签名源内容
* @return
*/
public static String sign(String prikeyvalue, String sign_str) {
try {
//【1】获取私钥
KeyFactory keyFactory = KeyFactory.getInstance(PaymentConstant.SIGN_TYPE);
//将BASE64编码的私钥字符串进行解码
BASE64Decoder decoder = new BASE64Decoder();
byte[] encodeByte = decoder.decodeBuffer(prikeyvalue);
//生成私钥对象
PrivateKey privatekey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodeByte));
//【2】使用私钥
// 获取Signature实例,指定签名算法(本例使用SHA1WithRSA)
Signature signature = Signature.getInstance(PaymentConstant.MD5_WITH_RSA);
//加载私钥
signature.initSign(privatekey);
//更新待签名的数据
signature.update(sign_str.getBytes(BaseConstant.CHARSET));
//进行签名
byte[] signed = signature.sign();
//将加密后的字节数组,转换成BASE64编码的字符串,作为最终的签名数据
return new String(org.apache.commons.codec.binary.Base64.encodeBase64(signed));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 签名验证
*
* @param lianPubkey 下载好的连连公钥
* @param lianSignSrc 连连的签名原串,也就是将返回串封装成jsonObject
* @param lianSigned 连连加密签名签名,包括签名原串+私钥
* @return
*/
public static boolean checksign(String lianPubkey, String lianSigned,
String lianSignSrc) {
try {
//【1】获取公钥
//获取KeyFactory,指定RSA算法
KeyFactory keyFactory = KeyFactory.getInstance(PaymentConstant.SIGN_TYPE);
//将BASE64编码的公钥字符串进行解码
BASE64Decoder decoder = new BASE64Decoder();
//将BASE64解码后的字节数组,构造成X509EncodedKeySpec对象,生成公钥对象
PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(decoder.decodeBuffer(lianPubkey)));
byte[] signed = decoder.decodeBuffer(lianSigned);
//【2】使用公钥,进行验签
//获取Signature实例,指定签名算法(与之前一致)
Signature signature = Signature.getInstance(PaymentConstant.MD5_WITH_RSA);
//加载公钥
signature.initVerify(publicKey);
//更新原数据
signature.update(lianSignSrc.getBytes(BaseConstant.CHARSET));
//公钥验签(true-验签通过;false-验签失败)
return signature.verify(signed);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
解决问题
于是,和连连那边协商,其提供一个新的jar包,替换jdk安装目录下的两个jar包和JRE目录下的两个jar包,如图所示:
这样,就完美解决问题了,下载地址:jar包下载地址
相关文章
- Java实现 LeetCode 639解码方法 2(递推)
- Java实现 LeetCode 169 多数元素
- Java实现 蓝桥杯 算法训练 景点游览
- java实现整数翻转
- java实现第四届蓝桥杯错误票据
- java实现第四届蓝桥杯错误票据
- Java实现提取拼音首字母
- Java实现 蓝桥杯 历届试题 错误票据
- java struts2入门学习---中文验证、对错误消息的分离、结果(result)类型细节配置
- 【JAVA】input.next().charAt(0);的含义
- Atitit php java python nodejs错误日志功能的比较
- keytool 错误: java.lang.Exception: 密钥库文件存在, 但为空: E:xxxxxx.jks
- JAVA字符串数学公式运算-辅助类-支持浮点数错误纠正-低消耗-高可用性-小数点后面保留16位小数
- Java:URLEncoder、URLDecoder、Base64编码与解码
- 解决Cause: java.sql.SQLException: sql injection violation, dbType mysql ... token IDENTIFIER deleted错误
- 多种方法解决java.sql.SQLSyntaxErrorException: Unknown database ‘xxx‘的错误
- 一文优化java.lang.StackOverflowError的堆栈溢出问题及递归引发的java.lang.StackOverflowError错误
- 解决java或jsp中的For input string的错误
- 【错误记录】Android Studio 编译报错 ( The dependency contains Java 8 bytecode. Please enable desugaring by )
- 【错误记录】IntelliJ IDEA 中右键点击源码目录选择 New 选项 没有创建 Java Class 选项 ( 将对应的源码目录标记为 Sources 选项 )
- Java Swing JFileChooser和JColorChooser:文件选择器和颜色选择器
- FileNotFoundException: java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset 错误解决
- Paper‘s imageable width is too small.Java控制标签打印机的错误现象解决