私钥配置说明.md 7.6 KB

SM2私钥配置说明

概述

签名服务器支持多种方式配置私钥和公钥,您可以选择最适合您使用场景的方式。


配置方式(按优先级从高到低)

1. 通过API接口传入(推荐)⭐

优点:

  • 最灵活,每次请求可以使用不同的私钥
  • 支持多租户场景
  • 无需重启服务器
  • 私钥不需要存储在服务器上

缺点:

  • 需要在每次请求中传递私钥
  • 需要客户端妥善保管私钥

使用方法:

签名时传入私钥:

curl -X POST http://localhost:8888/api/sign \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "version": "1.0",
      "txnType": "20250",
      "reqOrgId": "201811200001003"
    },
    "priKey": "您的64位十六进制私钥",
    "reqOrgNo": "您的机构号"
  }'

验签时传入公钥:

curl -X POST http://localhost:8888/api/verify \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "version": "1.0",
      "txnType": "20250"
    },
    "sign": "签名字符串",
    "pubKey": "您的130位十六进制公钥",
    "reqOrgNo": "您的机构号"
  }'

2. 通过命令行参数

优点:

  • 启动时指定,灵活方便
  • 适合脚本自动化部署

缺点:

  • 私钥可能在进程列表中可见(不够安全)
  • 修改需要重启服务

使用方法:

# 语法:
java -cp "bin:lib/*" demo.com.SignServer [配置文件路径] [机构号] [私钥] [公钥]

# 示例:
java -cp "bin:lib/*" demo.com.SignServer \
  "" \
  "201811200001003" \
  "3164EE0DF2BCA7A12309383E3305DD6563A28DFE53F65BBD60B3A1D7F80AC275" \
  "046875695CDF1EF046ABB231FDAFA6DCA2AF1E5719EAC00DE80D65FEF03F8485DC9DCBBC10A9A46D565B4CDCEE3510F276209657CAE5BAC10C9678583A44F7F100"

3. 通过环境变量(推荐用于生产环境)⭐

优点:

  • 相对安全,私钥不会出现在代码或命令行中
  • 适合容器化部署(Docker、K8s)
  • 便于CI/CD集成

缺点:

  • 修改需要重启服务

使用方法:

# 设置环境变量
export SM2_PRIVATE_KEY="您的64位十六进制私钥"
export SLT_PUBLIC_KEY="您的130位十六进制公钥"
export REQ_ORG_NO="您的机构号"

# 启动服务
java -cp "bin:lib/*" demo.com.SignServer

Docker示例:

docker run -d \
  -e SM2_PRIVATE_KEY="您的私钥" \
  -e SLT_PUBLIC_KEY="您的公钥" \
  -e REQ_ORG_NO="您的机构号" \
  -p 8888:8888 \
  your-sign-server

4. 通过配置文件

优点:

  • 集中管理配置
  • 易于维护
  • 支持多个配置项

缺点:

  • 私钥存储在文件中,需要注意文件权限
  • 修改需要重启服务

使用方法:

  1. 创建配置文件 config.properties

    # 机构配置
    reqOrgNo=201811200001003
    
    # SM2私钥(64位十六进制)
    priKey=3164EE0DF2BCA7A12309383E3305DD6563A28DFE53F65BBD60B3A1D7F80AC275
    
    # 平台公钥(130位十六进制)
    sltPubKey=046875695CDF1EF046ABB231FDAFA6DCA2AF1E5719EAC00DE80D65FEF03F8485DC9DCBBC10A9A46D565B4CDCEE3510F276209657CAE5BAC10C9678583A44F7F100
    
  2. 设置文件权限(重要!):

    chmod 600 config.properties
    
  3. 启动服务:

    # 使用默认配置文件(config.properties)
    java -cp "bin:lib/*" demo.com.SignServer
    
    # 或指定配置文件路径
    java -cp "bin:lib/*" demo.com.SignServer /path/to/your/config.properties
    

5. 代码中的默认配置

优点:

  • 开箱即用,适合快速测试

缺点:

  • 不安全,不适合生产环境
  • 私钥写死在代码中
  • 修改需要重新编译

使用方法:

修改 SignServer.java 文件:

// 请求机构号
private static String reqOrgNo = "您的机构号";
// 请求机构的私钥
private static String priKey = "您的SM2私钥";
// 平台给商户的公钥
private static String sltPubKey = "您的SM2公钥";

然后重新编译并启动。


配置优先级

当多种配置方式同时存在时,优先级为:

API接口传入 > 命令行参数 > 环境变量 > 配置文件 > 代码默认值

说明

  • 高优先级的配置会覆盖低优先级的配置
  • 如果某个参数在高优先级中未设置,则使用低优先级的值

使用场景建议

场景1:开发测试

建议: 使用 API接口传入配置文件

  • 快速测试不同的密钥
  • 便于调试

场景2:生产环境(单机部署)

建议: 使用 配置文件 + 严格的文件权限

  • 集中管理
  • 注意设置 chmod 600 保护配置文件

场景3:生产环境(容器化)

建议: 使用 环境变量Secret管理

  • 与Kubernetes Secrets或Docker Secrets集成
  • 不将私钥写入镜像

场景4:多租户SaaS服务

建议: 使用 API接口传入

  • 每个租户使用自己的密钥
  • 服务器不存储任何私钥
  • 最安全的方案

安全建议

⚠️ 重要安全提示

  1. 永远不要将私钥提交到代码仓库

    # 添加到 .gitignore
    config.properties
    *.key
    
  2. 使用配置文件时,严格限制文件权限

    chmod 600 config.properties
    chown app_user:app_group config.properties
    
  3. 生产环境建议使用密钥管理服务

    • AWS KMS
    • Azure Key Vault
    • HashiCorp Vault
  4. 启用HTTPS

    • 如果通过API传递私钥,必须使用HTTPS
    • 防止私钥在网络传输中被窃取
  5. 日志脱敏

    • 服务器日志中会隐藏私钥中间部分
    • 格式:3164EE0D...F80AC275

SM2密钥格式说明

私钥格式

  • 长度: 64位十六进制字符(32字节)
  • 示例: 3164EE0DF2BCA7A12309383E3305DD6563A28DFE53F65BBD60B3A1D7F80AC275
  • 字符集: 0-9, A-F(大小写均可)

公钥格式(非压缩)

  • 长度: 130位十六进制字符(65字节)
  • 前缀: 04(表示非压缩格式)
  • 示例: 046875695CDF1EF046ABB231FDAFA6DCA2AF1E5719EAC00DE80D65FEF03F8485DC9DCBBC10A9A46D565B4CDCEE3510F276209657CAE5BAC10C9678583A44F7F100

常见问题

Q1: 私钥格式错误怎么办?

A: 确保私钥是64位的十六进制字符串,不包含空格、换行等其他字符。

Q2: 可以在一次请求中只传私钥,不传机构号吗?

A: 可以,如果不传机构号,会使用服务器配置的默认机构号。

Q3: API传入的私钥会被服务器保存吗?

A: 不会,私钥仅在当次请求中使用,请求结束后立即释放,不会持久化存储。

Q4: 多个客户端可以使用不同的私钥吗?

A: 可以,通过API接口传入私钥的方式,每个客户端都可以使用自己的私钥。


快速测试

启动服务器后,测试不同配置方式:

# 测试1:使用服务器默认配置
curl -X POST http://localhost:8888/api/sign \
  -H "Content-Type: application/json" \
  -d '{"data": {"version": "1.0"}}'

# 测试2:传入自定义私钥
curl -X POST http://localhost:8888/api/sign \
  -H "Content-Type: application/json" \
  -d '{
    "data": {"version": "1.0"},
    "priKey": "3164EE0DF2BCA7A12309383E3305DD6563A28DFE53F65BBD60B3A1D7F80AC275",
    "reqOrgNo": "TEST123"
  }'

总结

选择合适的配置方式取决于您的具体需求:

配置方式 灵活性 安全性 适用场景
API传入 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ 多租户、SaaS
命令行参数 ⭐⭐⭐⭐ ⭐⭐ 脚本部署
环境变量 ⭐⭐⭐ ⭐⭐⭐⭐ 容器化部署
配置文件 ⭐⭐ ⭐⭐⭐ 单机部署
代码默认值 仅供测试

生产环境推荐: API传入(多租户)或 环境变量(单租户)