wz-golang-server/docs/security_and_payload_crypto.md

3.9 KiB
Raw Blame History

接口安全校验与请求/响应加密说明

本文档说明系统已有的两套机制:

  1. 安全校验(请求头签名)
  2. 请求/响应参数加解密AES-GCM

并给出前端对接方式与示例。

一、机制概览

1. 安全校验(签名)

  • 入口中间件:server/middleware/security.go
  • 目的:防止非法请求与重放
  • 校验内容:请求头签名 + 时间戳
  • 有效期5 分钟内
  • 白名单:/swagger//swagger/index.html

2. 请求/响应加解密Payload Crypto

  • 入口中间件:server/middleware/payload_crypto.go
  • 加密算法AES-GCM密钥来自 payload_crypto.secret_key
  • 加密载荷结构:
    • nonceBase64
    • ciphertextBase64
  • 可独立控制:
    • 仅加密响应
    • 仅解密请求
    • 请求强制加密

二、当前开发环境默认行为config.dev.yaml

  • security.enable = false
    • 不要求签名头
  • payload_crypto.enable = true
    • 框架开启,但请求/响应方向开关关闭
  • payload_crypto.request.enable = false
  • payload_crypto.response.enable = false

结论:开发环境默认不需要前端计算签名,也不会返回加密响应。

三、前端对接方式

1. 安全校验(签名)对接

security.enable = true 时必须携带:

  • X-App-Timestamp:毫秒时间戳
  • X-App-SignMD5(timestamp + secretKey)
    • secretKey 来自 security.secret_key

请求示例(伪代码):

timestamp = 当前毫秒时间戳
sign = md5(timestamp + secretKey)
Headers:
  X-App-Timestamp: <timestamp>
  X-App-Sign: <sign>

注意:

  • 服务器允许时间偏差 5 分钟。
  • 若请求不在白名单且缺少签名或时间戳,将返回 403。

2. 请求加密(可选)

payload_crypto.enable = truepayload_crypto.request.enable = true 时:

  • payload_crypto.request.required = true,所有请求必须加密。
  • required = false,是否加密由请求头决定。

请求头:

  • X-App-Encrypt: 1(头名来自 payload_crypto.header_key

请求体格式JSON

{
  "nonce": "Base64Nonce",
  "ciphertext": "Base64Ciphertext"
}

加解密规则:

  • AES-GCM
  • nonce 长度使用 GCM 标准长度12 bytes编码后为 Base64 字符串)
  • 明文为原始 JSON 请求体

3. 响应加密(可选)

payload_crypto.enable = truepayload_crypto.response.enable = true 时:

  • 服务端返回加密响应
  • 响应头会带:X-App-Encrypt: 1
  • 响应体同样为:
{
  "nonce": "Base64Nonce",
  "ciphertext": "Base64Ciphertext"
}

前端处理流程:

  1. 判断响应头 X-App-Encrypt 是否为真(非空、非 0、非 false
  2. 若为真,用 payload_crypto.secret_key 进行 AES-GCM 解密。
  3. 解密得到的明文即为原始 JSON 响应。

四、密钥派生规则(前端需要一致)

加密密钥派生规则在 server/common/payload_crypto.go

  1. secret_key 是 Base64且解码后长度为 16/24/32 字节,直接使用。
  2. 否则若 secret_key 的原始长度为 16/24/32 字节,直接使用原始字节。
  3. 否则对 secret_key 做 SHA-256取 32 字节作为 AES key。

前端必须严格按上述规则派生密钥,否则无法解密。

五、建议的对接策略

  • 开发联调:先关闭签名与加密,仅验证业务流程。
  • 灰度/生产:
    • 开启 security.enable,强制签名校验。
    • 按需开启 payload_crypto.response.enable,保护敏感响应。
    • 若需要强制请求加密,再开启 payload_crypto.request.required

六、相关配置位置

  • 安全校验配置:server/config/config.*.yaml -> security
  • 加解密配置:server/config/config.*.yaml -> payload_crypto
  • 中间件实现:
    • server/middleware/security.go
    • server/middleware/payload_crypto.go
  • 加解密工具:server/common/payload_crypto.go