|
@@ -1,6 +1,6 @@
|
|
|
package common.utils.hyg;
|
|
package common.utils.hyg;
|
|
|
|
|
|
|
|
-import com.jfinal.kit.StrKit; // 仍然保留,因为您有 JFinal 框架
|
|
|
|
|
|
|
+import com.jfinal.kit.StrKit;
|
|
|
|
|
|
|
|
import javax.crypto.Cipher;
|
|
import javax.crypto.Cipher;
|
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
@@ -10,7 +10,7 @@ import java.security.interfaces.RSAPrivateKey;
|
|
|
import java.security.interfaces.RSAPublicKey;
|
|
import java.security.interfaces.RSAPublicKey;
|
|
|
import java.security.spec.PKCS8EncodedKeySpec;
|
|
import java.security.spec.PKCS8EncodedKeySpec;
|
|
|
import java.security.spec.X509EncodedKeySpec;
|
|
import java.security.spec.X509EncodedKeySpec;
|
|
|
-import java.util.*; // 导入 Java 8+ 的标准 Base64 类
|
|
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
|
|
|
public class RSAUtils {
|
|
public class RSAUtils {
|
|
|
// 密钥算法
|
|
// 密钥算法
|
|
@@ -20,11 +20,11 @@ public class RSAUtils {
|
|
|
// 加密/解密算法及填充方式, RSA默认使用PKCS1Padding
|
|
// 加密/解密算法及填充方式, RSA默认使用PKCS1Padding
|
|
|
public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
|
|
public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
|
|
|
|
|
|
|
|
- // 密钥长度,这里使用1024位,也可以是2048等
|
|
|
|
|
- private static final int KEY_SIZE = 1024;
|
|
|
|
|
|
|
+ // 密钥长度,这里使用1024位
|
|
|
|
|
+ private static final int KEY_SIZE = 1024; // 也可以是 2048 等
|
|
|
|
|
|
|
|
// 存储公钥和私钥的Map键
|
|
// 存储公钥和私钥的Map键
|
|
|
- private static final String PUBLIC_KEY = "RSAPublicKey";
|
|
|
|
|
|
|
+ private static final String PUBLIC_KEY = "RSAPublicyKey";
|
|
|
private static final String PRIVATE_KEY = "RSAPrivateKey";
|
|
private static final String PRIVATE_KEY = "RSAPrivateKey";
|
|
|
|
|
|
|
|
// RSA加密最大分段大小 (对于1024位RSA密钥,PKCS1Padding填充,最大加密长度为128-11=117字节)
|
|
// RSA加密最大分段大小 (对于1024位RSA密钥,PKCS1Padding填充,最大加密长度为128-11=117字节)
|
|
@@ -44,7 +44,7 @@ public class RSAUtils {
|
|
|
*/
|
|
*/
|
|
|
public static Map<String, Key> genKeyPair() throws Exception {
|
|
public static Map<String, Key> genKeyPair() throws Exception {
|
|
|
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
|
|
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
|
|
|
- keyPairGen.initialize(KEY_SIZE); // 初始化密钥长度
|
|
|
|
|
|
|
+ keyPairGen.initialize(KEY_SIZE);
|
|
|
KeyPair keyPair = keyPairGen.generateKeyPair();
|
|
KeyPair keyPair = keyPairGen.generateKeyPair();
|
|
|
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
|
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
|
|
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
|
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
|
@@ -63,14 +63,15 @@ public class RSAUtils {
|
|
|
* @throws Exception 如果签名过程中发生错误
|
|
* @throws Exception 如果签名过程中发生错误
|
|
|
*/
|
|
*/
|
|
|
public static String sign(byte[] data, String privateKey) throws Exception {
|
|
public static String sign(byte[] data, String privateKey) throws Exception {
|
|
|
- byte[] keyBytes = Base64.getDecoder().decode(privateKey); // 改用 java.util.Base64
|
|
|
|
|
|
|
+ byte[] keyBytes = Base64.getDecoder().decode(privateKey);
|
|
|
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
|
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
|
- PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
|
|
|
|
|
|
+ PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); // 可能会在此处抛出 InvalidKeySpecException
|
|
|
|
|
+
|
|
|
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
|
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
|
|
signature.initSign(privateK);
|
|
signature.initSign(privateK);
|
|
|
signature.update(data);
|
|
signature.update(data);
|
|
|
- return Base64.getEncoder().encodeToString(signature.sign()); // 改用 java.util.Base64
|
|
|
|
|
|
|
+ return Base64.getEncoder().encodeToString(signature.sign());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -83,14 +84,15 @@ public class RSAUtils {
|
|
|
* @throws Exception 如果验证签名过程中发生错误
|
|
* @throws Exception 如果验证签名过程中发生错误
|
|
|
*/
|
|
*/
|
|
|
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
|
|
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
|
|
|
- byte[] keyBytes = Base64.getDecoder().decode(publicKey); // 改用 java.util.Base64
|
|
|
|
|
|
|
+ byte[] keyBytes = Base64.getDecoder().decode(publicKey);
|
|
|
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
|
|
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
|
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
|
PublicKey publicK = keyFactory.generatePublic(keySpec);
|
|
PublicKey publicK = keyFactory.generatePublic(keySpec);
|
|
|
|
|
+
|
|
|
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
|
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
|
|
signature.initVerify(publicK);
|
|
signature.initVerify(publicK);
|
|
|
signature.update(data);
|
|
signature.update(data);
|
|
|
- return signature.verify(Base64.getDecoder().decode(sign)); // 改用 java.util.Base64
|
|
|
|
|
|
|
+ return signature.verify(Base64.getDecoder().decode(sign));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -102,13 +104,13 @@ public class RSAUtils {
|
|
|
* @throws Exception 如果解密过程中发生错误
|
|
* @throws Exception 如果解密过程中发生错误
|
|
|
*/
|
|
*/
|
|
|
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
|
|
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
|
|
|
- byte[] keyBytes = Base64.getDecoder().decode(privateKey); // 改用 java.util.Base64
|
|
|
|
|
|
|
+ byte[] keyBytes = Base64.getDecoder().decode(privateKey);
|
|
|
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
|
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
|
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
|
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
|
|
|
|
|
|
|
- Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); // 明确指定算法和填充方式
|
|
|
|
|
- cipher.init(Cipher.DECRYPT_MODE, privateK); // 解密模式
|
|
|
|
|
|
|
+ Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
|
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, privateK);
|
|
|
|
|
|
|
|
int inputLen = encryptedData.length;
|
|
int inputLen = encryptedData.length;
|
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
@@ -116,13 +118,10 @@ public class RSAUtils {
|
|
|
byte[] cache;
|
|
byte[] cache;
|
|
|
// 对数据分段解密
|
|
// 对数据分段解密
|
|
|
while (inputLen - offSet > 0) {
|
|
while (inputLen - offSet > 0) {
|
|
|
- if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
|
|
|
|
- cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
|
|
|
|
- } else {
|
|
|
|
|
- cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ int actualBlockSize = (inputLen - offSet > MAX_DECRYPT_BLOCK) ? MAX_DECRYPT_BLOCK : (inputLen - offSet);
|
|
|
|
|
+ cache = cipher.doFinal(encryptedData, offSet, actualBlockSize);
|
|
|
out.write(cache, 0, cache.length);
|
|
out.write(cache, 0, cache.length);
|
|
|
- offSet += cache.length; // 实际解密字节数
|
|
|
|
|
|
|
+ offSet += actualBlockSize; // 修正 offSet 推进逻辑
|
|
|
}
|
|
}
|
|
|
byte[] decryptedData = out.toByteArray();
|
|
byte[] decryptedData = out.toByteArray();
|
|
|
out.close();
|
|
out.close();
|
|
@@ -139,13 +138,13 @@ public class RSAUtils {
|
|
|
* @throws Exception 如果解密过程中发生错误
|
|
* @throws Exception 如果解密过程中发生错误
|
|
|
*/
|
|
*/
|
|
|
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
|
|
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
|
|
|
- byte[] keyBytes = Base64.getDecoder().decode(publicKey); // 改用 java.util.Base64
|
|
|
|
|
|
|
+ byte[] keyBytes = Base64.getDecoder().decode(publicKey);
|
|
|
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
|
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
|
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
|
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
|
|
|
|
|
|
|
- Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); // 明确指定算法和填充方式
|
|
|
|
|
- cipher.init(Cipher.DECRYPT_MODE, publicK); // 解密模式
|
|
|
|
|
|
|
+ Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
|
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, publicK);
|
|
|
|
|
|
|
|
int inputLen = encryptedData.length;
|
|
int inputLen = encryptedData.length;
|
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
@@ -153,13 +152,10 @@ public class RSAUtils {
|
|
|
byte[] cache;
|
|
byte[] cache;
|
|
|
// 对数据分段解密
|
|
// 对数据分段解密
|
|
|
while (inputLen - offSet > 0) {
|
|
while (inputLen - offSet > 0) {
|
|
|
- if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
|
|
|
|
- cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
|
|
|
|
- } else {
|
|
|
|
|
- cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ int actualBlockSize = (inputLen - offSet > MAX_DECRYPT_BLOCK) ? MAX_DECRYPT_BLOCK : (inputLen - offSet);
|
|
|
|
|
+ cache = cipher.doFinal(encryptedData, offSet, actualBlockSize);
|
|
|
out.write(cache, 0, cache.length);
|
|
out.write(cache, 0, cache.length);
|
|
|
- offSet += cache.length; // 实际解密字节数
|
|
|
|
|
|
|
+ offSet += actualBlockSize; // 修正 offSet 推进逻辑
|
|
|
}
|
|
}
|
|
|
byte[] decryptedData = out.toByteArray();
|
|
byte[] decryptedData = out.toByteArray();
|
|
|
out.close();
|
|
out.close();
|
|
@@ -175,13 +171,13 @@ public class RSAUtils {
|
|
|
* @throws Exception 如果加密过程中发生错误
|
|
* @throws Exception 如果加密过程中发生错误
|
|
|
*/
|
|
*/
|
|
|
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
|
|
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
|
|
|
- byte[] keyBytes = Base64.getDecoder().decode(publicKey); // 改用 java.util.Base64
|
|
|
|
|
|
|
+ byte[] keyBytes = Base64.getDecoder().decode(publicKey);
|
|
|
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
|
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
|
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
|
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
|
|
|
|
|
|
|
- Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); // 明确指定算法和填充方式
|
|
|
|
|
- cipher.init(Cipher.ENCRYPT_MODE, publicK); // 加密模式
|
|
|
|
|
|
|
+ Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
|
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, publicK);
|
|
|
|
|
|
|
|
int inputLen = data.length;
|
|
int inputLen = data.length;
|
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
@@ -189,15 +185,10 @@ public class RSAUtils {
|
|
|
byte[] cache;
|
|
byte[] cache;
|
|
|
// 对数据分段加密
|
|
// 对数据分段加密
|
|
|
while (inputLen - offSet > 0) {
|
|
while (inputLen - offSet > 0) {
|
|
|
- if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
|
|
|
|
- // 如果剩余数据大于最大加密块,加密一个完整块
|
|
|
|
|
- cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
|
|
|
|
- } else {
|
|
|
|
|
- // 加密剩余的所有数据
|
|
|
|
|
- cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ int actualBlockSize = (inputLen - offSet > MAX_ENCRYPT_BLOCK) ? MAX_ENCRYPT_BLOCK : (inputLen - offSet);
|
|
|
|
|
+ cache = cipher.doFinal(data, offSet, actualBlockSize);
|
|
|
out.write(cache, 0, cache.length);
|
|
out.write(cache, 0, cache.length);
|
|
|
- offSet += MAX_ENCRYPT_BLOCK; // 每次偏移一个加密块大小
|
|
|
|
|
|
|
+ offSet += actualBlockSize; // 修正 offSet 推进逻辑 (这里是 inputLen)
|
|
|
}
|
|
}
|
|
|
byte[] encryptedData = out.toByteArray();
|
|
byte[] encryptedData = out.toByteArray();
|
|
|
out.close();
|
|
out.close();
|
|
@@ -214,13 +205,13 @@ public class RSAUtils {
|
|
|
* @throws Exception 如果加密过程中发生错误
|
|
* @throws Exception 如果加密过程中发生错误
|
|
|
*/
|
|
*/
|
|
|
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
|
|
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
|
|
|
- byte[] keyBytes = Base64.getDecoder().decode(privateKey); // 改用 java.util.Base64
|
|
|
|
|
|
|
+ byte[] keyBytes = Base64.getDecoder().decode(privateKey);
|
|
|
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
|
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
|
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
|
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
|
|
|
|
|
|
|
- Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); // 明确指定算法和填充方式
|
|
|
|
|
- cipher.init(Cipher.ENCRYPT_MODE, privateK); // 加密模式
|
|
|
|
|
|
|
+ Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
|
|
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, privateK);
|
|
|
|
|
|
|
|
int inputLen = data.length;
|
|
int inputLen = data.length;
|
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
@@ -228,13 +219,10 @@ public class RSAUtils {
|
|
|
byte[] cache;
|
|
byte[] cache;
|
|
|
// 对数据分段加密
|
|
// 对数据分段加密
|
|
|
while (inputLen - offSet > 0) {
|
|
while (inputLen - offSet > 0) {
|
|
|
- if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
|
|
|
|
- cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
|
|
|
|
- } else {
|
|
|
|
|
- cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ int actualBlockSize = (inputLen - offSet > MAX_ENCRYPT_BLOCK) ? MAX_ENCRYPT_BLOCK : (inputLen - offSet);
|
|
|
|
|
+ cache = cipher.doFinal(data, offSet, actualBlockSize);
|
|
|
out.write(cache, 0, cache.length);
|
|
out.write(cache, 0, cache.length);
|
|
|
- offSet += MAX_ENCRYPT_BLOCK; // 每次偏移一个加密块大小
|
|
|
|
|
|
|
+ offSet += actualBlockSize; // 修正 offSet 推进逻辑 (这里是 inputLen)
|
|
|
}
|
|
}
|
|
|
byte[] encryptedData = out.toByteArray();
|
|
byte[] encryptedData = out.toByteArray();
|
|
|
out.close();
|
|
out.close();
|
|
@@ -250,7 +238,7 @@ public class RSAUtils {
|
|
|
*/
|
|
*/
|
|
|
public static String getPrivateKey(Map<String, Key> keyMap) throws Exception {
|
|
public static String getPrivateKey(Map<String, Key> keyMap) throws Exception {
|
|
|
Key key = keyMap.get(PRIVATE_KEY);
|
|
Key key = keyMap.get(PRIVATE_KEY);
|
|
|
- return Base64.getEncoder().encodeToString(key.getEncoded()); // 改用 java.util.Base64
|
|
|
|
|
|
|
+ return Base64.getEncoder().encodeToString(key.getEncoded());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -262,7 +250,7 @@ public class RSAUtils {
|
|
|
*/
|
|
*/
|
|
|
public static String getPublicKey(Map<String, Key> keyMap) throws Exception {
|
|
public static String getPublicKey(Map<String, Key> keyMap) throws Exception {
|
|
|
Key key = keyMap.get(PUBLIC_KEY);
|
|
Key key = keyMap.get(PUBLIC_KEY);
|
|
|
- return Base64.getEncoder().encodeToString(key.getEncoded()); // 改用 java.util.Base64
|
|
|
|
|
|
|
+ return Base64.getEncoder().encodeToString(key.getEncoded());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -276,24 +264,15 @@ public class RSAUtils {
|
|
|
if (paramMap == null || paramMap.isEmpty()) {
|
|
if (paramMap == null || paramMap.isEmpty()) {
|
|
|
return "";
|
|
return "";
|
|
|
}
|
|
}
|
|
|
- // 将Map的Entry转换为List,以便排序
|
|
|
|
|
List<Map.Entry<String, Object>> list = new ArrayList<>(paramMap.entrySet());
|
|
List<Map.Entry<String, Object>> list = new ArrayList<>(paramMap.entrySet());
|
|
|
-
|
|
|
|
|
- // 使用Comparator按照Key的ASCII值进行排序
|
|
|
|
|
Collections.sort(list, Comparator.comparing(Map.Entry::getKey));
|
|
Collections.sort(list, Comparator.comparing(Map.Entry::getKey));
|
|
|
|
|
|
|
|
- // 拼接字符串
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
StringBuilder sb = new StringBuilder();
|
|
|
for (Map.Entry<String, Object> item : list) {
|
|
for (Map.Entry<String, Object> item : list) {
|
|
|
- // 过滤空值,通常规则是空值不参与签名
|
|
|
|
|
- // StrKit.isBlank() 会检查 null, "", " "
|
|
|
|
|
- if (!StrKit.isBlank(item.getKey()) && item.getValue() != null) { // value不能是null
|
|
|
|
|
- // 如果值是空字符串,根据业务需要决定是否拼接
|
|
|
|
|
- // 这里按原逻辑,如果值是空字符串,也会拼接
|
|
|
|
|
|
|
+ if (!StrKit.isBlank(item.getKey()) && item.getValue() != null) {
|
|
|
sb.append(item.getKey()).append("=").append(item.getValue()).append("&");
|
|
sb.append(item.getKey()).append("=").append(item.getValue()).append("&");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- // 移除末尾多余的'&'
|
|
|
|
|
if (sb.length() > 0) {
|
|
if (sb.length() > 0) {
|
|
|
return sb.substring(0, sb.length() - 1);
|
|
return sb.substring(0, sb.length() - 1);
|
|
|
}
|
|
}
|
|
@@ -358,7 +337,6 @@ public class RSAUtils {
|
|
|
boolean wrongSignVerified = verify(dataBytes, publicKey, wrongSign);
|
|
boolean wrongSignVerified = verify(dataBytes, publicKey, wrongSign);
|
|
|
System.out.println("验证签名结果 (正确数据与错误签名): " + wrongSignVerified);
|
|
System.out.println("验证签名结果 (正确数据与错误签名): " + wrongSignVerified);
|
|
|
} catch (IllegalArgumentException e) {
|
|
} catch (IllegalArgumentException e) {
|
|
|
- // java.util.Base64.getDecoder().decode() 在遇到非法Base64字符串时会抛出 IllegalArgumentException
|
|
|
|
|
System.out.println("验证签名结果 (正确数据与错误签名): Base64解码错误,签名非法。");
|
|
System.out.println("验证签名结果 (正确数据与错误签名): Base64解码错误,签名非法。");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -366,12 +344,12 @@ public class RSAUtils {
|
|
|
|
|
|
|
|
// 5. sortParam 方法测试
|
|
// 5. sortParam 方法测试
|
|
|
System.out.println("--- sortParam 方法测试 ---");
|
|
System.out.println("--- sortParam 方法测试 ---");
|
|
|
- Map<String, Object> params = new TreeMap<>(); // 使用TreeMap方便观察排序
|
|
|
|
|
|
|
+ Map<String, Object> params = new TreeMap<>();
|
|
|
params.put("appKey", "123");
|
|
params.put("appKey", "123");
|
|
|
params.put("timestamp", System.currentTimeMillis());
|
|
params.put("timestamp", System.currentTimeMillis());
|
|
|
params.put("paramA", "valueA");
|
|
params.put("paramA", "valueA");
|
|
|
params.put("paramC", "valueC");
|
|
params.put("paramC", "valueC");
|
|
|
- params.put("paramB", null); // 测试null值
|
|
|
|
|
|
|
+ params.put("paramB", null);
|
|
|
params.put("paramD", ""); // 测试空字符串
|
|
params.put("paramD", ""); // 测试空字符串
|
|
|
|
|
|
|
|
String sortedAndConcatenated = sortParam(params);
|
|
String sortedAndConcatenated = sortParam(params);
|
|
@@ -385,4 +363,4 @@ public class RSAUtils {
|
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
+}
|