8 changed files with 589 additions and 0 deletions
@ -0,0 +1,19 @@ |
|||||
|
package com.zdxt.enforcementcode.config; |
||||
|
|
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@Component |
||||
|
@ConfigurationProperties(prefix = "password-party") |
||||
|
public class PasswordPartyConfig { |
||||
|
|
||||
|
private String baseUrl; |
||||
|
|
||||
|
public String getBaseUrl() { |
||||
|
return baseUrl; |
||||
|
} |
||||
|
|
||||
|
public void setBaseUrl(String baseUrl) { |
||||
|
this.baseUrl = baseUrl; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
package com.zdxt.enforcementcode.domain.vo.passwordparty; |
||||
|
|
||||
|
public class KeyPairVo { |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
package com.zdxt.enforcementcode.domain.vo.passwordparty; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.io.Serial; |
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
@Data |
||||
|
public class SymmetryEncryptVo implements Serializable { |
||||
|
|
||||
|
@Serial |
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
private String outData; |
||||
|
|
||||
|
private String ivData; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
package com.zdxt.enforcementcode.service.thirdparty; |
||||
|
|
||||
|
import com.zdxt.enforcementcode.domain.vo.passwordparty.SymmetryEncryptVo; |
||||
|
|
||||
|
/** |
||||
|
* 密码服务平台 |
||||
|
* |
||||
|
* @author vincent |
||||
|
* @date 2026-09-22 |
||||
|
*/ |
||||
|
public interface IPasswordPartyService { |
||||
|
|
||||
|
/** |
||||
|
* HSM - 生成随机数 |
||||
|
* |
||||
|
* @param length 随机数长度 |
||||
|
* @return 随机数(Hex 16进制类型) |
||||
|
*/ |
||||
|
String generateRandom(int length); |
||||
|
|
||||
|
/** |
||||
|
* HSM - 对称加密 |
||||
|
* |
||||
|
* @param keyIndex 用户密钥号,填0时使用keyData作为密钥 |
||||
|
* @param algType 对称算法类型(SM1或SM4) |
||||
|
* @param key 外部密钥(keyIndex为0时生效,Hex 16进制) |
||||
|
* @param iv IV值,CBC/CFB/OFB模式时必传(Hex 16进制) |
||||
|
* @param inputData 加密原文(Hex 16进制) |
||||
|
* @return 对称加密结果 |
||||
|
*/ |
||||
|
SymmetryEncryptVo symmetryEncrypt(Integer keyIndex, int algType, String key, String iv, String inputData); |
||||
|
|
||||
|
/** |
||||
|
* HSM - 对称解密 |
||||
|
* |
||||
|
* @param keyIndex 用户密钥号,填0时使用keyData作为密钥 |
||||
|
* @param algType 对称算法类型(SM1或SM4) |
||||
|
* @param key 外部密钥(keyIndex为0时生效,Hex 16进制) |
||||
|
* @param iv IV值,CBC/CFB/OFB模式时必传(Hex 16进制) |
||||
|
* @param inputData 解密密文(Hex 16进制) |
||||
|
* @return 对称解密结果 |
||||
|
*/ |
||||
|
SymmetryEncryptVo symmetryDecrypt(Integer keyIndex, int algType, String key, String iv, String inputData); |
||||
|
|
||||
|
/** |
||||
|
* HSM - SM2签名 |
||||
|
* |
||||
|
* @param keyIndex 密钥索引 |
||||
|
* @param plainData 明文摘要(先使用杂凑接口计算摘要,Hex 16进制类型) |
||||
|
* @return 签名值(Hex 16进制类型) |
||||
|
*/ |
||||
|
String sm2SignData(Integer keyIndex, String plainData); |
||||
|
|
||||
|
/** |
||||
|
* HSM - SM2验签 |
||||
|
* |
||||
|
* @param algType 算法类型 |
||||
|
* @param publicKey 公钥(使用导出公钥接口获取,Hex 16进制类型) |
||||
|
* @param signValue 签名值(Hex 16进制类型) |
||||
|
* @param plainData 明文摘要(先使用杂凑接口计算摘要,Hex 16进制类型) |
||||
|
* @return true=验证通过, false=验证失败 |
||||
|
*/ |
||||
|
boolean sm2Verify(Integer algType, String publicKey, String signValue, String plainData); |
||||
|
|
||||
|
/** |
||||
|
* HSM - 非对称加密 |
||||
|
* |
||||
|
* @param algType 算法ID(请查阅算法字典) |
||||
|
* @param publcKey 公钥(Hex 16进制类型) |
||||
|
* @param data 明文(Hex 16进制类型) |
||||
|
* @return 加密密文(Hex 16进制类型) |
||||
|
*/ |
||||
|
String externalEncrypt(Integer algType, String publcKey, String data); |
||||
|
|
||||
|
/** |
||||
|
* HSM - 非对称解密 |
||||
|
* |
||||
|
* @param keyIndex 密钥索引 |
||||
|
* @param algId 算法ID(请查阅算法字典) |
||||
|
* @param enc 密文(Hex 16进制类型) |
||||
|
* @return 解密明文(Hex 16进制类型) |
||||
|
*/ |
||||
|
String internalDecrypt(Integer keyIndex, Integer algId, String enc); |
||||
|
|
||||
|
/** |
||||
|
* HSM - HMAC摘要 |
||||
|
* |
||||
|
* @param keyIndex 密钥索引(必填) |
||||
|
* @param key 密钥,非必传(Hex 16进制类型) |
||||
|
* @param algType 算法ID标签,请使用SM3(查阅算法字典) |
||||
|
* @param inputData 明文摘要(Hex 16进制类型,必填) |
||||
|
* @return HMAC值(Hex 16进制类型) |
||||
|
*/ |
||||
|
String hmacWithIndex(Integer keyIndex, String key, Integer algType, String inputData); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,179 @@ |
|||||
|
package com.zdxt.enforcementcode.service.thirdparty; |
||||
|
|
||||
|
import com.zdxt.enforcementcode.config.PasswordPartyConfig; |
||||
|
import com.zdxt.enforcementcode.domain.vo.passwordparty.SymmetryEncryptVo; |
||||
|
import com.zdxt.enforcementcode.service.thirdparty.impl.PasswordPartyServiceImpl; |
||||
|
|
||||
|
/** |
||||
|
* IPasswordPartyService 接口方法正向流程演示 |
||||
|
* <p> |
||||
|
* 运行前请确保: |
||||
|
* 1. HSM 密码服务平台已启动且网络可达 |
||||
|
* 2. 下方 BASE_URL 配置为正确的 HSM 服务地址 |
||||
|
* 3. HSM 中已配置好所需的密钥(密钥索引、算法类型等) |
||||
|
* </p> |
||||
|
* |
||||
|
* @author vincent |
||||
|
* @date 2026-09-22 |
||||
|
*/ |
||||
|
public class PasswordPartyDemo { |
||||
|
|
||||
|
/** HSM 密码服务平台地址,按实际环境修改 */ |
||||
|
private static final String BASE_URL = "http://localhost:8080"; |
||||
|
|
||||
|
/** 测试用密钥索引 */ |
||||
|
private static final int KEY_INDEX = 1; |
||||
|
|
||||
|
/** SM4 算法ID(按实际算法字典修改) */ |
||||
|
private static final int ALG_SM4 = 1; |
||||
|
|
||||
|
/** SM2 算法ID */ |
||||
|
private static final int ALG_SM2 = 2; |
||||
|
|
||||
|
/** SM3 算法ID */ |
||||
|
private static final int ALG_SM3 = 4; |
||||
|
|
||||
|
private static IPasswordPartyService service; |
||||
|
|
||||
|
/** |
||||
|
* 主入口:手动构造 PasswordPartyServiceImpl 实例,依次调用各接口方法验证正向流程 |
||||
|
* <p> |
||||
|
* 执行顺序: |
||||
|
* 1. 生成随机数 |
||||
|
* 2. 对称加密 → 对称解密(验证互为逆操作) |
||||
|
* 3. SM2签名 |
||||
|
* 4. 非对称加密 → 非对称解密(验证互为逆操作) |
||||
|
* 5. HMAC摘要 |
||||
|
* </p> |
||||
|
*/ |
||||
|
public static void main(String[] args) { |
||||
|
// 构造配置并初始化 Service 实例(不依赖 Spring 容器)
|
||||
|
PasswordPartyConfig config = new PasswordPartyConfig(); |
||||
|
config.setBaseUrl(BASE_URL); |
||||
|
service = new PasswordPartyServiceImpl(config); |
||||
|
|
||||
|
System.out.println("========== IPasswordPartyService 正向流程演示 ==========\n"); |
||||
|
|
||||
|
// 1. 生成随机数:验证 HSM 基础连通性
|
||||
|
testGenerateRandom(); |
||||
|
// 2. 对称加密 + 对称解密:使用 SM4 算法,验证加解密互为逆操作
|
||||
|
testSymmetryEncryptAndDecrypt(); |
||||
|
// 3. SM2签名:对摘要数据进行签名,验证签名值非空
|
||||
|
testSM2SignAndVerify(); |
||||
|
// 4. 非对称加密 + 非对称解密:使用 SM2 算法,验证加解密互为逆操作
|
||||
|
testAsymmetricEncryptAndDecrypt(); |
||||
|
// 5. HMAC摘要:使用 SM3 算法计算消息认证码
|
||||
|
testHmacWithIndex(); |
||||
|
|
||||
|
System.out.println("\n========== 全部演示完成 =========="); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 1. 生成随机数 |
||||
|
*/ |
||||
|
private static void testGenerateRandom() { |
||||
|
System.out.println("----- 1. 生成随机数 -----"); |
||||
|
String random = service.generateRandom(10); |
||||
|
System.out.println("随机数(10字节): " + random); |
||||
|
assertNotBlank("random", random); |
||||
|
|
||||
|
String random32 = service.generateRandom(32); |
||||
|
System.out.println("随机数(32字节): " + random32); |
||||
|
assertNotBlank("random32", random32); |
||||
|
System.out.println(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 2. 对称加密 + 对称解密(互为逆操作) |
||||
|
*/ |
||||
|
private static void testSymmetryEncryptAndDecrypt() { |
||||
|
System.out.println("----- 2. 对称加密 + 对称解密 -----"); |
||||
|
String plainHex = "31323334353637383132333435363738"; |
||||
|
|
||||
|
SymmetryEncryptVo encryptResult = service.symmetryEncrypt(KEY_INDEX, ALG_SM4, null, null, plainHex); |
||||
|
System.out.println("对称加密原文: " + plainHex); |
||||
|
System.out.println("对称加密密文: " + encryptResult.getOutData()); |
||||
|
assertNotBlank("encryptOutData", encryptResult.getOutData()); |
||||
|
|
||||
|
SymmetryEncryptVo decryptResult = service.symmetryDecrypt(KEY_INDEX, ALG_SM4, null, null, encryptResult.getOutData()); |
||||
|
System.out.println("对称解密结果: " + decryptResult.getOutData()); |
||||
|
assertNotBlank("decryptOutData", decryptResult.getOutData()); |
||||
|
|
||||
|
if (plainHex.equalsIgnoreCase(decryptResult.getOutData())) { |
||||
|
System.out.println("[PASS] 对称加密/解密互为逆操作,解密结果与原文一致"); |
||||
|
} else { |
||||
|
System.out.println("[WARN] 解密结果与原文不一致,请检查密钥配置"); |
||||
|
} |
||||
|
System.out.println(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 3. SM2签名 + SM2验签 |
||||
|
*/ |
||||
|
private static void testSM2SignAndVerify() { |
||||
|
System.out.println("----- 3. SM2签名 + SM2验签 -----"); |
||||
|
String plainDataHex = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; |
||||
|
|
||||
|
String signValue = service.sm2SignData(KEY_INDEX, plainDataHex); |
||||
|
System.out.println("SM2签名原文(摘要): " + plainDataHex); |
||||
|
System.out.println("SM2签名值: " + signValue); |
||||
|
assertNotBlank("signData", signValue); |
||||
|
|
||||
|
System.out.println("[PASS] SM2签名成功,签名值非空"); |
||||
|
System.out.println(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 4. 非对称加密 + 非对称解密 |
||||
|
*/ |
||||
|
private static void testAsymmetricEncryptAndDecrypt() { |
||||
|
System.out.println("----- 4. 非对称加密 + 非对称解密 -----"); |
||||
|
String plainHex = "31323334"; |
||||
|
|
||||
|
String publicKey = getTestPublicKey(); |
||||
|
String encryptData = service.externalEncrypt(ALG_SM2, publicKey, plainHex); |
||||
|
System.out.println("非对称加密原文: " + plainHex); |
||||
|
System.out.println("非对称加密密文: " + encryptData); |
||||
|
assertNotBlank("encryptData", encryptData); |
||||
|
|
||||
|
String decrypted = service.internalDecrypt(KEY_INDEX, ALG_SM2, encryptData); |
||||
|
System.out.println("非对称解密结果: " + decrypted); |
||||
|
assertNotBlank("decrypted", decrypted); |
||||
|
|
||||
|
if (plainHex.equalsIgnoreCase(decrypted)) { |
||||
|
System.out.println("[PASS] 非对称加密/解密互为逆操作,解密结果与原文一致"); |
||||
|
} else { |
||||
|
System.out.println("[WARN] 解密结果与原文不一致,请检查密钥配置"); |
||||
|
} |
||||
|
System.out.println(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 5. HMAC摘要 |
||||
|
*/ |
||||
|
private static void testHmacWithIndex() { |
||||
|
System.out.println("----- 5. HMAC摘要 -----"); |
||||
|
String inputDataHex = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; |
||||
|
|
||||
|
String hmac = service.hmacWithIndex(KEY_INDEX, null, ALG_SM3, inputDataHex); |
||||
|
System.out.println("HMAC输入摘要: " + inputDataHex); |
||||
|
System.out.println("HMAC输出值: " + hmac); |
||||
|
assertNotBlank("hmac", hmac); |
||||
|
System.out.println("[PASS] HMAC摘要成功,结果非空"); |
||||
|
System.out.println(); |
||||
|
} |
||||
|
|
||||
|
// ======================== 辅助方法 ========================
|
||||
|
|
||||
|
private static String getTestPublicKey() { |
||||
|
// TODO: 替换为 HSM 中实际导出的公钥(Hex 16进制)
|
||||
|
return "a746f6b47e9261adbf79e2af77d4b40919c01a85d9b11722c4bdd7cb36fa8ddad68c8abc96d73c986c6de1544c147e0b8208d98d9976facd8f00f312c7c5a90e"; |
||||
|
} |
||||
|
|
||||
|
private static void assertNotBlank(String fieldName, String value) { |
||||
|
if (value == null || value.isBlank()) { |
||||
|
throw new AssertionError("[FAIL] " + fieldName + " 返回值为空"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,264 @@ |
|||||
|
package com.zdxt.enforcementcode.service.thirdparty.impl; |
||||
|
|
||||
|
import cn.hutool.http.HttpRequest; |
||||
|
import cn.hutool.http.HttpResponse; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.zdxt.enforcementcode.config.PasswordPartyConfig; |
||||
|
import com.zdxt.enforcementcode.domain.vo.passwordparty.SymmetryEncryptVo; |
||||
|
import com.zdxt.enforcementcode.service.thirdparty.IPasswordPartyService; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.dromara.common.core.exception.base.BaseException; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
/** |
||||
|
* 密码服务平台 |
||||
|
* |
||||
|
* @author vincent |
||||
|
* @date 2026-09-22 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@RequiredArgsConstructor |
||||
|
@Service |
||||
|
public class PasswordPartyServiceImpl implements IPasswordPartyService { |
||||
|
|
||||
|
private final PasswordPartyConfig passwordPartyConfig; |
||||
|
|
||||
|
/** |
||||
|
* 生成随机数 |
||||
|
* |
||||
|
* @param length 随机数长度 |
||||
|
* @return 随机数(Hex 16进制类型) |
||||
|
*/ |
||||
|
@Override |
||||
|
public String generateRandom(int length) { |
||||
|
JSONObject params = new JSONObject(); |
||||
|
params.put("length", length); |
||||
|
|
||||
|
JSONObject data = callHsmApi("/hsm/api/GenerateRandom", params, "生成随机数"); |
||||
|
return data.getString("random"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 对称加密 |
||||
|
* |
||||
|
* @param keyIndex 用户密钥号,填0时使用keyData做密钥 |
||||
|
* @param algType 对称算法SM1或SM4 |
||||
|
* @param key 外部密钥,keyIndex为0时生效(Hex 16进制类型) |
||||
|
* @param iv IV值,CBC/CFB/OFB模式时必传(Hex 16进制类型) |
||||
|
* @param inputData 加密原文(Hex 16进制类型) |
||||
|
* @return 对称加密结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
public SymmetryEncryptVo symmetryEncrypt(Integer keyIndex, int algType, String key, String iv, String inputData) { |
||||
|
JSONObject params = buildSymmetryParams(keyIndex, algType, key, iv, inputData); |
||||
|
|
||||
|
JSONObject data = callHsmApi("/hsm/api/symmetryEncrypt", params, "对称加密"); |
||||
|
return buildSymmetryEncryptVo(data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 对称解密 |
||||
|
* |
||||
|
* @param keyIndex 用户密钥号,填0时使用keyData做密钥 |
||||
|
* @param algType 对称算法SM1或SM4 |
||||
|
* @param key 外部密钥,keyIndex为0时生效(Hex 16进制类型) |
||||
|
* @param iv IV值,CBC/CFB/OFB模式时必传(Hex 16进制类型) |
||||
|
* @param inputData 解密原文(Hex 16进制类型) |
||||
|
* @return 对称解密结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
public SymmetryEncryptVo symmetryDecrypt(Integer keyIndex, int algType, String key, String iv, String inputData) { |
||||
|
JSONObject params = buildSymmetryParams(keyIndex, algType, key, iv, inputData); |
||||
|
|
||||
|
JSONObject data = callHsmApi("/hsm/api/symmetryDecrypt", params, "对称解密"); |
||||
|
return buildSymmetryEncryptVo(data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* SM2签名 |
||||
|
* |
||||
|
* @param keyIndex 密钥索引 |
||||
|
* @param plainData 明文摘要,先使用杂凑接口计算摘要(Hex 16进制类型) |
||||
|
* @return 签名值(Hex 16进制类型) |
||||
|
*/ |
||||
|
@Override |
||||
|
public String sm2SignData(Integer keyIndex, String plainData) { |
||||
|
JSONObject params = new JSONObject(); |
||||
|
params.put("keyIndex", keyIndex); |
||||
|
params.put("plainData", plainData); |
||||
|
|
||||
|
JSONObject data = callHsmApi("/hsm/api/SM2SignData", params, "SM2签名"); |
||||
|
return data.getString("signData"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* SM2验签 |
||||
|
* |
||||
|
* @param algType 算法类型 |
||||
|
* @param publicKey 公钥,使用导出公钥接口获取(Hex 16进制类型) |
||||
|
* @param signValue 签名值(Hex 16进制类型) |
||||
|
* @param plainData 明文摘要,先使用杂凑接口计算摘要(Hex 16进制类型) |
||||
|
* @return true=验证通过 |
||||
|
*/ |
||||
|
@Override |
||||
|
public boolean sm2Verify(Integer algType, String publicKey, String signValue, String plainData) { |
||||
|
JSONObject params = new JSONObject(); |
||||
|
params.put("algType", algType); |
||||
|
params.put("publicKey", publicKey); |
||||
|
params.put("signValue", signValue); |
||||
|
params.put("plainData", plainData); |
||||
|
|
||||
|
doPost("/hsm/api/sm2Verify", params, "SM2验签"); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 非对称加密 |
||||
|
* |
||||
|
* @param algType 算法ID |
||||
|
* @param publcKey 公钥(Hex 16进制类型) |
||||
|
* @param data 明文(Hex 16进制类型) |
||||
|
* @return 加密密文(Hex 16进制类型) |
||||
|
*/ |
||||
|
@Override |
||||
|
public String externalEncrypt(Integer algType, String publcKey, String data) { |
||||
|
JSONObject params = new JSONObject(); |
||||
|
params.put("algType", algType); |
||||
|
params.put("publcKey", publcKey); |
||||
|
params.put("data", data); |
||||
|
|
||||
|
JSONObject result = callHsmApi("/hsm/api/externalEncrypt", params, "非对称加密"); |
||||
|
return result.getString("encryptData"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 非对称解密 |
||||
|
* |
||||
|
* @param keyIndex 密钥索引 |
||||
|
* @param algId 算法ID |
||||
|
* @param enc 密文(Hex 16进制类型) |
||||
|
* @return 解密明文(Hex 16进制类型) |
||||
|
*/ |
||||
|
@Override |
||||
|
public String internalDecrypt(Integer keyIndex, Integer algId, String enc) { |
||||
|
JSONObject params = new JSONObject(); |
||||
|
params.put("keyIndex", keyIndex); |
||||
|
params.put("algId", algId); |
||||
|
params.put("enc", enc); |
||||
|
|
||||
|
JSONObject data = callHsmApi("/hsm/api/internalDecrypt", params, "非对称解密"); |
||||
|
return data.getString("plainData"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* HMAC摘要 |
||||
|
* |
||||
|
* @param keyIndex 密钥索引(必填) |
||||
|
* @param key 密钥,非必传(Hex 16进制类型) |
||||
|
* @param algType 算法ID标签,请使用SM3 |
||||
|
* @param inputData 明文摘要(Hex 16进制类型,必填) |
||||
|
* @return HMAC值(Hex 16进制类型) |
||||
|
*/ |
||||
|
@Override |
||||
|
public String hmacWithIndex(Integer keyIndex, String key, Integer algType, String inputData) { |
||||
|
JSONObject params = new JSONObject(); |
||||
|
params.put("keyIndex", keyIndex); |
||||
|
if (key != null) { |
||||
|
params.put("key", key); |
||||
|
} |
||||
|
params.put("algType", algType); |
||||
|
params.put("inputData", inputData); |
||||
|
|
||||
|
JSONObject data = callHsmApi("/hsm/api/HmacWithIndex", params, "HMAC"); |
||||
|
return data.getString("hmac"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 构建对称加密/解密的公共请求参数 |
||||
|
*/ |
||||
|
private JSONObject buildSymmetryParams(Integer keyIndex, int algType, String key, String iv, String inputData) { |
||||
|
JSONObject params = new JSONObject(); |
||||
|
params.put("keyIndex", keyIndex); |
||||
|
params.put("algType", algType); |
||||
|
if (key != null) { |
||||
|
params.put("key", key); |
||||
|
} |
||||
|
if (iv != null) { |
||||
|
params.put("iv", iv); |
||||
|
} |
||||
|
params.put("inputData", inputData); |
||||
|
return params; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 组装对称加密/解密的响应VO |
||||
|
*/ |
||||
|
private SymmetryEncryptVo buildSymmetryEncryptVo(JSONObject data) { |
||||
|
SymmetryEncryptVo vo = new SymmetryEncryptVo(); |
||||
|
vo.setOutData(data.getString("outData")); |
||||
|
vo.setIvData(data.getString("ivData")); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* HSM接口公共调用方法(含data非空校验) |
||||
|
* |
||||
|
* @param apiPath 接口路径 |
||||
|
* @param params 请求参数 |
||||
|
* @param apiName 接口名称,用于日志和异常信息 |
||||
|
* @return 响应中的data节点 |
||||
|
*/ |
||||
|
private JSONObject callHsmApi(String apiPath, JSONObject params, String apiName) { |
||||
|
JSONObject jsonObject = doPost(apiPath, params, apiName); |
||||
|
|
||||
|
JSONObject data = jsonObject.getJSONObject("data"); |
||||
|
if (data == null) { |
||||
|
throw new BaseException("HSM" + apiName + "响应data为空"); |
||||
|
} |
||||
|
return data; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* HSM接口底层HTTP调用(POST + 状态码校验 + code校验) |
||||
|
* |
||||
|
* @param apiPath 接口路径 |
||||
|
* @param params 请求参数 |
||||
|
* @param apiName 接口名称,用于日志和异常信息 |
||||
|
* @return 完整响应JSON |
||||
|
*/ |
||||
|
private JSONObject doPost(String apiPath, JSONObject params, String apiName) { |
||||
|
try { |
||||
|
String url = passwordPartyConfig.getBaseUrl() + apiPath; |
||||
|
log.info("HSM{}请求URL: {}, 参数: {}", apiName, url, params); |
||||
|
|
||||
|
HttpResponse response = HttpRequest.post(url) |
||||
|
.header("Content-Type", "application/json;charset=utf-8") |
||||
|
.body(params.toJSONString()) |
||||
|
.timeout(10000) |
||||
|
.execute(); |
||||
|
|
||||
|
if (!response.isOk()) { |
||||
|
response.close(); |
||||
|
throw new BaseException("HSM" + apiName + "接口调用失败,HTTP状态码:" + response.getStatus()); |
||||
|
} |
||||
|
|
||||
|
String result = response.body(); |
||||
|
response.close(); |
||||
|
log.info("HSM{}响应: {}", apiName, result); |
||||
|
|
||||
|
JSONObject jsonObject = JSONObject.parseObject(result); |
||||
|
int code = jsonObject.getIntValue("code"); |
||||
|
if (code != 0) { |
||||
|
throw new BaseException("HSM" + apiName + "失败: " + jsonObject.getString("msg")); |
||||
|
} |
||||
|
return jsonObject; |
||||
|
} catch (BaseException e) { |
||||
|
throw e; |
||||
|
} catch (Exception e) { |
||||
|
log.error("HSM{}异常", apiName, e); |
||||
|
throw new BaseException("HSM" + apiName + "异常: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue