优化签名验证算法

This commit is contained in:
六如
2025-11-12 09:22:18 +08:00
parent 7599c51f80
commit 6e356abf1e
4 changed files with 115 additions and 105 deletions

View File

@@ -2,6 +2,7 @@
## 日常更新
- 2025-11-12优化签名验证算法
- 2025-11-05添加SDK示例返回List。详见com.gitee.sop.sdk.SdkTest.testList
- 2025-11-01添加回调处理。有升级SQL[sop-20251101.sql](./upgrade/sop-20251101.sql)
- 2025-09-12修复推送文档报找不到@Open注解问题

View File

@@ -36,10 +36,10 @@ import java.util.Map;
*/
public class SignUtil {
private static final String SIGN_TYPE_RSA = "RSA";
private static final String SIGN_TYPE_RSA2 = "RSA2";
private static final String SIGN_ALGORITHMS = "SHA1WithRSA";
private static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
private static final String RSA = "RSA";
private static final String RSA2 = "RSA2";
private static final String SHA1_WITH_RSA = "SHA1WithRSA";
private static final String SHA256_WITH_RSA = "SHA256WithRSA";
private static final String CHARSET_GBK = "GBK";
/**
@@ -85,9 +85,9 @@ public class SignUtil {
public static String rsaSign(String content, String publicKey, String charset,
String signType) throws SignException {
if (SIGN_TYPE_RSA.equals(signType)) {
if (RSA.equals(signType)) {
return rsaSign(content, publicKey, charset);
} else if (SIGN_TYPE_RSA2.equals(signType)) {
} else if (RSA2.equals(signType)) {
return rsa256Sign(content, publicKey, charset);
} else {
throw new SignException(ErrorEnum.ISV_INVALID_SIGNATURE_TYPE);
@@ -107,11 +107,11 @@ public class SignUtil {
String charset) throws SignException {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
PrivateKey priKey = getPrivateKeyFromPKCS8(RSA,
new ByteArrayInputStream(privateKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_SHA256RSA_ALGORITHMS);
.getInstance(SHA256_WITH_RSA);
signature.initSign(priKey);
@@ -141,11 +141,11 @@ public class SignUtil {
public static String rsaSign(String content, String publicKey,
String charset) throws SignException {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
PrivateKey priKey = getPrivateKeyFromPKCS8(RSA,
new ByteArrayInputStream(publicKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
.getInstance(SHA1_WITH_RSA);
signature.initSign(priKey);
@@ -262,29 +262,32 @@ public class SignUtil {
public static boolean rsaCheck(String content, String sign, String publicKey, String charset,
String signType) throws SignException {
if (SIGN_TYPE_RSA.equals(signType)) {
if (RSA.equals(signType)) {
return rsaCheckContent(content, sign, publicKey, charset);
} else if (SIGN_TYPE_RSA2.equals(signType)) {
} else if (RSA2.equals(signType)) {
return rsa256CheckContent(content, sign, publicKey, charset);
} else {
throw new SignException(ErrorEnum.ISV_INVALID_SIGNATURE_TYPE);
}
}
/**
* 使用公钥验证签名
*
* @param content 原始数据
* @param sign 签名值(Base64编码)
* @param publicKey 公钥
* @return 验证是否成功
* @throws SignException 验证过程中的异常
*/
public static boolean rsa256CheckContent(String content, String sign, String publicKey,
String charset) throws SignException {
try {
PublicKey pubKey = getPublicKeyFromX509("RSA",
new ByteArrayInputStream(publicKey.getBytes()));
PublicKey pubKey = getPublicKeyFromX509(RSA, new ByteArrayInputStream(publicKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_SHA256RSA_ALGORITHMS);
.getInstance(SHA256_WITH_RSA);
signature.initVerify(pubKey);
@@ -294,7 +297,7 @@ public class SignUtil {
signature.update(content.getBytes(charset));
}
return signature.verify(Base64.decodeBase64(sign.getBytes()));
return signature.verify(java.util.Base64.getDecoder().decode(sign));
} catch (Exception e) {
throw new SignException(ErrorEnum.ISV_INVALID_SIGNATURE, e);
}
@@ -303,11 +306,11 @@ public class SignUtil {
public static boolean rsaCheckContent(String content, String sign, String publicKey,
String charset) throws SignException {
try {
PublicKey pubKey = getPublicKeyFromX509("RSA",
PublicKey pubKey = getPublicKeyFromX509(RSA,
new ByteArrayInputStream(publicKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
.getInstance(SHA1_WITH_RSA);
signature.initVerify(pubKey);
@@ -317,7 +320,7 @@ public class SignUtil {
signature.update(content.getBytes(charset));
}
return signature.verify(Base64.decodeBase64(sign.getBytes()));
return signature.verify(java.util.Base64.getDecoder().decode(sign));
} catch (Exception e) {
throw new SignException(ErrorEnum.ISV_INVALID_SIGNATURE, e);
}
@@ -520,9 +523,9 @@ public class SignUtil {
public static String rsaEncrypt(String content, String publicKey,
String charset) throws SignException {
try {
PublicKey pubKey = getPublicKeyFromX509(SIGN_TYPE_RSA,
PublicKey pubKey = getPublicKeyFromX509(RSA,
new ByteArrayInputStream(publicKey.getBytes()));
Cipher cipher = Cipher.getInstance(SIGN_TYPE_RSA);
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] data = StringUtils.isEmpty(charset) ? content.getBytes()
: content.getBytes(charset);
@@ -563,9 +566,9 @@ public class SignUtil {
public static String rsaDecrypt(String content, String publicKey,
String charset) throws SignException {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
PrivateKey priKey = getPrivateKeyFromPKCS8(RSA,
new ByteArrayInputStream(publicKey.getBytes()));
Cipher cipher = Cipher.getInstance(SIGN_TYPE_RSA);
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, priKey);
byte[] encryptedData = StringUtils.isEmpty(charset)
? Base64.decodeBase64(content.getBytes())

View File

@@ -1,7 +1,6 @@
package com.gitee.sop.sdk.sign;
import com.gitee.sop.sdk.util.Base64Util;
import javax.crypto.Cipher;
@@ -26,29 +25,36 @@ import java.util.Map;
*/
public class SignUtil {
/** RSA最大加密明文大小 */
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/** RSA最大解密密文大小 */
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
public static final String SIGN_TYPE_RSA = "RSA";
public static final String RSA = "RSA";
/**
* sha256WithRsa 算法请求类型
*/
public static final String SIGN_TYPE_RSA2 = "RSA2";
public static final String RSA2 = "RSA2";
public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
public static final String SHA1_WITH_RSA = "SHA1WithRSA";
public static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
public static final String SHA256_WITH_RSA = "SHA256WithRSA";
/** GBK字符集 **/
/**
* GBK字符集
**/
public static final String CHARSET_GBK = "GBK";
/**
* 获取签名内容
*
* @param sortedParams
* @return
*/
@@ -70,23 +76,20 @@ public class SignUtil {
/**
* rsa内容签名
*
* @param content
* @param privateKey
* @param charset
* @return
* @throws SopSignException
* @param content 内容
* @param privateKey 私钥
* @param charset 字符集
* @return 返回签名
* @throws SopSignException 报错异常
*/
public static String rsaSign(String content, String privateKey, String charset,
String signType) throws SopSignException {
if (SIGN_TYPE_RSA.equals(signType)) {
if (RSA.equals(signType)) {
return rsaSign(content, privateKey, charset);
} else if (SIGN_TYPE_RSA2.equals(signType)) {
} else if (RSA2.equals(signType)) {
return rsa256Sign(content, privateKey, charset);
} else {
throw new SopSignException("Sign Type is Not Support : signType=" + signType);
}
@@ -105,11 +108,11 @@ public class SignUtil {
String charset) throws SopSignException {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
PrivateKey priKey = getPrivateKeyFromPKCS8(RSA,
new ByteArrayInputStream(privateKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_SHA256RSA_ALGORITHMS);
.getInstance(SHA256_WITH_RSA);
signature.initSign(priKey);
@@ -140,11 +143,11 @@ public class SignUtil {
public static String rsaSign(String content, String privateKey,
String charset) throws SopSignException {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
PrivateKey priKey = getPrivateKeyFromPKCS8(RSA,
new ByteArrayInputStream(privateKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
.getInstance(SHA1_WITH_RSA);
signature.initSign(priKey);
@@ -237,11 +240,11 @@ public class SignUtil {
}
public static boolean rsaCheckV1(Map<String, String> params, String publicKey,
String charset,String signType) throws SopSignException {
String charset, String signType) throws SopSignException {
String sign = params.get("sign");
String content = getSignCheckContentV1(params);
return rsaCheck(content, sign, publicKey, charset,signType);
return rsaCheck(content, sign, publicKey, charset, signType);
}
public static boolean rsaCheckV2(Map<String, String> params, String publicKey,
@@ -253,21 +256,21 @@ public class SignUtil {
}
public static boolean rsaCheckV2(Map<String, ?> params, String publicKey,
String charset,String signType) throws SopSignException {
String charset, String signType) throws SopSignException {
String sign = String.valueOf(params.get("sign"));
String content = getSignCheckContentV2(params);
return rsaCheck(content, sign, publicKey, charset,signType);
return rsaCheck(content, sign, publicKey, charset, signType);
}
public static boolean rsaCheck(String content, String sign, String publicKey, String charset,
String signType) throws SopSignException {
if (SIGN_TYPE_RSA.equals(signType)) {
if (RSA.equals(signType)) {
return rsaCheckContent(content, sign, publicKey, charset);
} else if (SIGN_TYPE_RSA2.equals(signType)) {
} else if (RSA2.equals(signType)) {
return rsa256CheckContent(content, sign, publicKey, charset);
@@ -285,7 +288,7 @@ public class SignUtil {
new ByteArrayInputStream(publicKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_SHA256RSA_ALGORITHMS);
.getInstance(SHA256_WITH_RSA);
signature.initVerify(pubKey);
@@ -295,7 +298,7 @@ public class SignUtil {
signature.update(content.getBytes(charset));
}
return signature.verify(Base64Util.decodeBase64(sign.getBytes()));
return signature.verify(java.util.Base64.getDecoder().decode(sign));
} catch (Exception e) {
throw new SopSignException(
"RSAcontent = " + content + ",sign=" + sign + ",charset = " + charset, e);
@@ -309,7 +312,7 @@ public class SignUtil {
new ByteArrayInputStream(publicKey.getBytes()));
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
.getInstance(SHA1_WITH_RSA);
signature.initVerify(pubKey);
@@ -319,7 +322,7 @@ public class SignUtil {
signature.update(content.getBytes(charset));
}
return signature.verify(Base64Util.decodeBase64(sign.getBytes()));
return signature.verify(java.util.Base64.getDecoder().decode(sign));
} catch (Exception e) {
throw new SopSignException(
"RSAcontent = " + content + ",sign=" + sign + ",charset = " + charset, e);
@@ -352,6 +355,7 @@ public class SignUtil {
* <br>charset=UTF-8
* <br>}
* </p>
*
* @param params
* @param alipayPublicKey 支付宝公钥
* @param cusPrivateKey 商户私钥
@@ -390,6 +394,7 @@ public class SignUtil {
* <br>charset=UTF-8
* <br>}
* </p>
*
* @param params
* @param alipayPublicKey 支付宝公钥
* @param cusPrivateKey 商户私钥
@@ -404,7 +409,7 @@ public class SignUtil {
String charset = params.get("charset");
String bizContent = params.get("biz_content");
if (isCheckSign) {
if (!rsaCheckV2(params, alipayPublicKey, charset,signType)) {
if (!rsaCheckV2(params, alipayPublicKey, charset, signType)) {
throw new SopSignException("rsaCheck failure:rsaParams=" + params);
}
}
@@ -419,6 +424,7 @@ public class SignUtil {
/**
* 加密并签名<br>
* <b>目前适用于公众号</b>
*
* @param bizContent 待加密、签名内容
* @param alipayPublicKey 支付宝公钥
* @param cusPrivateKey 商户私钥
@@ -472,6 +478,7 @@ public class SignUtil {
/**
* 加密并签名<br>
* <b>目前适用于公众号</b>
*
* @param bizContent 待加密、签名内容
* @param alipayPublicKey 支付宝公钥
* @param cusPrivateKey 商户私钥
@@ -492,7 +499,7 @@ public class SignUtil {
*/
public static String encryptAndSign(String bizContent, String alipayPublicKey,
String cusPrivateKey, String charset, boolean isEncrypt,
boolean isSign,String signType) throws SopSignException {
boolean isSign, String signType) throws SopSignException {
StringBuilder sb = new StringBuilder();
if (StringUtils.isEmpty(charset)) {
charset = CHARSET_GBK;
@@ -538,9 +545,9 @@ public class SignUtil {
public static String rsaEncrypt(String content, String publicKey,
String charset) throws SopSignException {
try {
PublicKey pubKey = getPublicKeyFromX509(SIGN_TYPE_RSA,
PublicKey pubKey = getPublicKeyFromX509(RSA,
new ByteArrayInputStream(publicKey.getBytes()));
Cipher cipher = Cipher.getInstance(SIGN_TYPE_RSA);
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] data = StringUtils.isEmpty(charset) ? content.getBytes()
: content.getBytes(charset);
@@ -583,9 +590,9 @@ public class SignUtil {
public static String rsaDecrypt(String content, String privateKey,
String charset) throws SopSignException {
try {
PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
PrivateKey priKey = getPrivateKeyFromPKCS8(RSA,
new ByteArrayInputStream(privateKey.getBytes()));
Cipher cipher = Cipher.getInstance(SIGN_TYPE_RSA);
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, priKey);
byte[] encryptedData = StringUtils.isEmpty(charset)
? Base64Util.decodeBase64(content.getBytes())

View File

@@ -33,7 +33,6 @@ public class AlipayClientPostTest extends TestBase {
app_auth_token String 否 40 详见应用授权概述
biz_content String 是 请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档
*/
// 这个请求会路由到story服务
@Test
public void testGet() throws Exception {