复现问题
之前在对接第三方连连支付的接口时,报出如下错误:
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包下载地址
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99235.html