Table of Contents
18.11 服务端解密流程
当前服务端按以下顺序处理,其他语言服务若实现同协议也必须保持失败关闭:
- 判断是否为
/tieup/api/v1/**,并在读取 body 前排除握手、上传、回调和OPTIONS。 - 根据 APP 版本头或 H5 环境变量解析加密策略;未知 APP 版本返回
4609。 - 判断 GET 是否存在
e,或写请求 Content-Type 是否为加密类型;强制模式下明文返回4606。 - 校验
X-Device-Id、X-Session-Id及 Redis Session 绑定关系。 - 用最终方法、URI path 和客户端上下文构造 AAD。
- Base64URL 解码外层信封和
n/c/t,校验版本、IV 和 Tag 长度。 - 使用 Session Key 执行 AES-256-GCM 认证解密;任何密文、Tag 或 AAD 篡改返回
4606。 - 校验时间戳、request ID、nonce 和
data,通过 Redis 原子消费 nonce。 - GET 使用
withQueryParams(data);写请求使用withParsedBody(data)并恢复 JSON body/Content-Type。 - 将重写后的请求写回请求上下文,再交给验证、鉴权和 Controller。
PHP 密码核心等价代码:
$plaintext = openssl_decrypt(
$ciphertext,
'aes-256-gcm',
$sessionKeyRaw,
OPENSSL_RAW_DATA,
$iv,
$tag,
$aad
);
if ($plaintext === false) {
throw new BusinessException(ResultCode::API_ENCRYPTION_PAYLOAD_INVALID);
}
不得记录握手密钥、Session Key、解密后的敏感业务参数或完整密文。策略缓存只保存数据库中的密钥封装值,不能缓存明文版本密钥。