# 接口安全校验与请求/响应加密说明 本文档说明系统已有的两套机制: 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` - 加密载荷结构: - `nonce`:Base64 - `ciphertext`:Base64 - 可独立控制: - 仅加密响应 - 仅解密请求 - 请求强制加密 ## 二、当前开发环境默认行为(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-Sign`:`MD5(timestamp + secretKey)` - `secretKey` 来自 `security.secret_key` 请求示例(伪代码): ```text timestamp = 当前毫秒时间戳 sign = md5(timestamp + secretKey) Headers: X-App-Timestamp: X-App-Sign: ``` 注意: - 服务器允许时间偏差 5 分钟。 - 若请求不在白名单且缺少签名或时间戳,将返回 403。 ### 2. 请求加密(可选) 当 `payload_crypto.enable = true` 且 `payload_crypto.request.enable = true` 时: - 若 `payload_crypto.request.required = true`,所有请求必须加密。 - 若 `required = false`,是否加密由请求头决定。 请求头: - `X-App-Encrypt: 1`(头名来自 `payload_crypto.header_key`) 请求体格式(JSON): ```json { "nonce": "Base64Nonce", "ciphertext": "Base64Ciphertext" } ``` 加解密规则: - AES-GCM - nonce 长度使用 GCM 标准长度(12 bytes,编码后为 Base64 字符串) - 明文为原始 JSON 请求体 ### 3. 响应加密(可选) 当 `payload_crypto.enable = true` 且 `payload_crypto.response.enable = true` 时: - 服务端返回加密响应 - 响应头会带:`X-App-Encrypt: 1` - 响应体同样为: ```json { "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`