mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-11-13 09:46:09 +08:00
优化签名验证算法
This commit is contained in:
@@ -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注解问题
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -33,7 +33,6 @@ public class AlipayClientPostTest extends TestBase {
|
||||
app_auth_token String 否 40 详见应用授权概述
|
||||
biz_content String 是 请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档
|
||||
*/
|
||||
// 这个请求会路由到story服务
|
||||
@Test
|
||||
public void testGet() throws Exception {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user