# authapi-sdk
**Repository Path**: ufudig/authapi-sdk
## Basic Information
- **Project Name**: authapi-sdk
- **Description**: 公开服务用RSA签名/加密开发库
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-09-07
- **Last Updated**: 2026-02-04
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Auth Api SDK
公共服务RSA签名/加密开发库
## 添加依赖
```xml
com.touscm
authapi-sdk
1.0-SNAPSHOT
```
## 签名算法
### 获取签名
签名使用基于非对称密钥的SHA256-RSA的数字签名算法, 具体处理如下:
原始字符 = 请求方法 + "\n" + 请求路由 + "\n" + 时间戳 + "\n" + 随机字符 + "\n" + 请求体 + "\n"
签名字符 = 使用 `SHA256withRSA` 算法签名原始字符
认证类型 = 如果配置了 `auth-api.auth-type`, 认证类型的值为配置的值, 如果未配置认证类型为 `OPEN-SHA256-RSA2048`
认证标识字段名 = 如果配置了 `auth-api.cert-identity`, 认证标识字段名为配置的值, 如果未配置则值为 `merchant_id`
认证信息 = 认证类型 + " " + 认证标识字段名 + "=" + 认证标识值 + ",nonce_str=" + 随机字符 + ",signature=" + 签名 + ",timestamp=" + 时间戳 + ",serial_no=" + 证书序号
### 加密算法
加密算法使用SM4(ECB模式, 填充格式为PKCS5Padding)加密请求体内容
## 示例代码
### 配置信息
```yaml
auth-api:
auth-type: 签名/验签标识类型(默认:OPEN-SHA256-RSA2048)
cert-identity: 认证标识字段名(例如:app-id或者merchant-id)
cert-root-path: 私钥/证书的根目录
cert-prefix: 私钥/证书文件名前缀
```
### 调用服务
#### SM4加密/解密
```java
public void testSm4() throws NoSuchAlgorithmException, NoSuchProviderException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidKeyException {
var key = Sm4Utils.generateKey();
System.out.println("Key: " + key);
var body = """
{
"app_id": "app_dc8643cf-bae6-4713-8511-75723e88095c",
"business_mode": "00",
"created_time": "20250605095528",
"end_time": "20250605095533",
"fee_amt": "0.00",
"freeze_stat": "UNFREEZE",
"id": "002212025060509552710776517720207020032",
"notifyToWxLiteFlag": "01",
"order_no": "P1930443317366820866",
"party_order_id": "02242506053572761009492",
"pay_amt": "1020.00",
"pay_channel": "wx_lite",
"real_amt": "1020.00",
"share_eq": "Y",
"status": "succeeded"
}
""";
// SM4加密
var encryptBody = Sm4Utils.encryptEcb(key, body);
System.out.println("encryptBody: " + encryptBody);
// SM4解密
var decryptBody = Sm4Utils.decryptEcb(key, encryptBody);
System.out.println("decryptBody: " + decryptBody);
assertEquals(body, decryptBody);
}
```
#### 生成私钥/证书
```java
@Bean
public CommandLineRunner testSdk(SignAuthService signAuthService) {
return args -> {
// 认证标识值, 例如:商户ID/应用ID
var certIdentity = "APP-ID-000000";
// 证书序号
var certSerialNo = 2025;
// 请求方法
var method = "POST";
// 请求路由
var openApiUri = "/open/api/v1";
// 请求体
var body = """
{
"app_id": "app_dc8643cf-bae6-4713-8511-75723e88095c",
"business_mode": "00",
"created_time": "20250605095528",
"end_time": "20250605095533",
"fee_amt": "0.00",
"freeze_stat": "UNFREEZE",
"id": "002212025060509552710776517720207020032",
"notifyToWxLiteFlag": "01",
"order_no": "P1930443317366820866",
"party_order_id": "02242506053572761009492",
"pay_amt": "1020.00",
"pay_channel": "wx_lite",
"real_amt": "1020.00",
"share_eq": "Y",
"status": "succeeded"
}
""";
// RSA加密, 可根据需要加密敏感字段(注意, 犹豫RSA算法长度限制, 2048位的RSA密钥加密原始字符长度上限为214位)
// 由于RSA的限制, 使用SM4对请求体进行整体加密
var json = JSONObject.parseObject(body);
var originValue = json.getString("id");
var encryptValue = signAuthService.rsaEncrypt(certIdentity, originValue);
System.out.println("encrypt");
System.out.println("originValue=" + originValue + ",encryptValue=" + encryptValue);
json.replace("id", encryptValue);
var requestBody = json.toJSONString();
// gen cert
signAuthService.generateCert(certIdentity, certSerialNo);
// RSA签名
var authContent = signAuthService.getAuthorization(certIdentity, certSerialNo, openApiUri, method, requestBody);
System.out.println("sign");
System.out.println(EntryUtils.toString(authContent));
// RSA验签
var verifyResult = signAuthService.authCheck(method, openApiUri, authContent, requestBody, new HashMap<>());
System.out.println("verify sign");
System.out.println(EntryUtils.toString(verifyResult));
// RSA字段解密, 实际使用可替换为SM4
var requestJson = JSONObject.parseObject(requestBody);
var requestEncryptValue = requestJson.getString("id");
var decryptResult = signAuthService.rsaDecrypt(certIdentity, requestEncryptValue);
System.out.println("decrypt");
System.out.println(EntryUtils.toString(decryptResult));
};
}
```