# 签名服务API使用说明 ## 服务介绍 这是一个基于SM2算法的HTTP签名服务,提供数据签名和验签功能。 ## 启动服务 ```bash cd /Users/light/www/pros/xingfutong-java java -cp "bin:lib/*" demo.com.SignServer ``` 服务启动后将监听 **8888端口** ## API接口说明 ### 1. 健康检查接口 **接口地址**: `GET http://localhost:8888/api/health` **功能**: 检查服务是否正常运行 **响应示例**: ```json { "status": "ok", "timestamp": 1761288550040 } ``` --- ### 2. 签名接口 **接口地址**: `POST http://localhost:8888/api/sign` **功能**: 对传入的数据进行SM2签名 **请求头**: ``` Content-Type: application/json ``` **请求参数**: ```json { "data": { "key1": "value1", "key2": "value2", ... }, "priKey": "您的SM2私钥(可选)", "reqOrgNo": "机构号(可选)" } ``` **参数说明**: - `data`: 对象类型,必填,包含需要签名的所有键值对 - `priKey`: 字符串类型,可选,SM2私钥(十六进制格式)。如不提供则使用服务器配置的默认私钥 - `reqOrgNo`: 字符串类型,可选,请求机构号。如不提供则使用服务器配置的默认机构号 - 系统会自动将key转为大写,并按字母顺序排序 - 空值字段会被自动过滤 **响应示例**: ```json { "success": true, "signData": "KEY1=value1|KEY2=value2", "sign": "304402206FC7DE55665BE3C062355D88A9A77AE5877FE3D5B42EBB3EAA46AF50E08DB53A0220105E6C4399B50825E98D6816FBF9B6D2E4603EB5EB6F5440F60728EDD8D0BA46", "timestamp": 1761288550594 } ``` **响应字段说明**: - `success`: 是否成功 - `signData`: 实际签名的数据串(按KEY升序排列) - `sign`: 十六进制签名结果 - `timestamp`: 时间戳 **使用示例1 - 使用默认私钥**: ```bash curl -X POST http://localhost:8888/api/sign \ -H "Content-Type: application/json" \ -d '{ "data": { "version": "1.0", "txnType": "20250", "reqOrgId": "201811200001003", "cardNo": "9206068000000010425" } }' ``` **使用示例2 - 传入自定义私钥**: ```bash curl -X POST http://localhost:8888/api/sign \ -H "Content-Type: application/json" \ -d '{ "data": { "version": "1.0", "txnType": "20250", "reqOrgId": "201811200001003" }, "priKey": "您的SM2私钥(64位十六进制字符串)", "reqOrgNo": "您的机构号" }' ``` --- ### 3. 验签接口 **接口地址**: `POST http://localhost:8888/api/verify` **功能**: 验证签名是否正确 **请求头**: ``` Content-Type: application/json ``` **请求参数**: ```json { "data": { "key1": "value1", "key2": "value2", ... }, "sign": "签名字符串", "pubKey": "公钥(可选)", "reqOrgNo": "机构号(可选)" } ``` **参数说明**: - `data`: 对象类型,必填,包含需要验签的所有键值对 - `sign`: 字符串类型,必填,待验证的签名(十六进制格式) - `pubKey`: 字符串类型,可选,SM2公钥(十六进制格式)。如不提供则使用服务器配置的默认公钥 - `reqOrgNo`: 字符串类型,可选,请求机构号。如不提供则使用服务器配置的默认机构号 **响应示例**: ```json { "success": true, "valid": true, "signData": "KEY1=value1|KEY2=value2", "timestamp": 1761288550803 } ``` **响应字段说明**: - `success`: 请求是否成功 - `valid`: 签名是否有效 - `signData`: 实际验签的数据串 - `timestamp`: 时间戳 **使用示例1 - 使用默认公钥**: ```bash curl -X POST http://localhost:8888/api/verify \ -H "Content-Type: application/json" \ -d '{ "data": { "version": "1.0", "txnType": "20250", "reqOrgId": "201811200001003" }, "sign": "304402206FC7DE55665BE3C062355D88A9A77AE5877FE3D5B42EBB3EAA46AF50E08DB53A..." }' ``` **使用示例2 - 传入自定义公钥**: ```bash curl -X POST http://localhost:8888/api/verify \ -H "Content-Type: application/json" \ -d '{ "data": { "version": "1.0", "txnType": "20250", "reqOrgId": "201811200001003" }, "sign": "304402206FC7DE55665BE3C062355D88A9A77AE5877FE3D5B42EBB3EAA46AF50E08DB53A...", "pubKey": "您的SM2公钥(130位十六进制字符串)", "reqOrgNo": "您的机构号" }' ``` --- ## 错误响应 当发生错误时,返回格式如下: ```json { "success": false, "error": "错误信息", "timestamp": 1761288550848 } ``` **常见错误**: - `data参数不能为空` - 签名/验签时data对象为空 - `data和sign参数不能为空` - 验签时缺少必要参数 - `只支持POST请求` - 使用了错误的HTTP方法 --- ## 快速测试 项目提供了测试脚本,可以快速测试所有接口: ```bash ./test_sign_api.sh ``` 测试脚本会自动执行以下测试: 1. 健康检查 2. 简单参数签名 3. 完整参数签名 4. 签名验证 5. 错误处理测试 --- ## 签名规则说明 1. **字段处理**: - 所有key会转换为大写 - 空值字段会被过滤 - 按key的字母顺序升序排列 2. **签名串生成**: - 格式: `KEY1=value1|KEY2=value2|KEY3=value3` - 使用竖线(|)分隔各字段 - 使用等号(=)连接key和value 3. **签名算法**: - 使用SM2国密算法 - 编码方式: UTF-8 - 输出格式: 十六进制字符串 --- ## 注意事项 1. 服务默认监听8888端口,如端口被占用请修改 `SignServer.java` 中的端口配置 2. 签名使用的私钥和机构号已在代码中配置 3. 验签使用的是平台公钥,与签名私钥不是配对的,所以验签测试会返回false(这是正常现象) 4. 如需在生产环境使用,请修改配置并确保密钥安全 --- ## 配置说明 在 `SignServer.java` 中可以配置: ```java // 请求机构号 private static String reqOrgNo = "201811200001003"; // 请求机构的私钥 private static String priKey = "3164EE0DF2BCA7A12309383E3305DD6563A28DFE53F65BBD60B3A1D7F80AC275"; // 平台给商户的公钥 private static String sltPubKey = "046875695CDF1EF046ABB231FDAFA6DCA2AF1E5719EAC00DE80D65FEF03F8485DC9DCBBC10A9A46D565B4CDCEE3510F276209657CAE5BAC10C9678583A44F7F100"; ``` --- ## 联系支持 如有问题,请检查: 1. 服务是否正常启动 2. 端口是否被占用 3. 请求格式是否正确 4. 参数是否完整