Skip to content

报文加解密及签名

AES 加密 / 解密

请求 Body 使用 AES 对称加密,加解密双方使用相同密钥。

算法参数

参数
AES 密钥平台下发给商户(32 位)
初始化向量(IV)16 个 0(即 0000000000000000
加密模式AES-256-CBC
输出格式Base64

加解密流程

加密:Body 明文  →  AES-256-CBC(密钥 + IV)  →  Base64 密文(aesBuffer)
解密:Base64 密文 →  AES-256-CBC 解密(密钥 + IV)  →  Body 明文

加密 Demo 见 附录 - 测试信息及 Demo

RSA 签名 / 验签(SHA256withRSA)

Header 中的 signature 字段由商户使用 RSA 私钥对请求 Body 明文 JSON 字符串签名生成;平台响应报文的签名由商户使用平台公钥对 data 解密后的明文 JSON 字符串验证。

密钥交换流程

  1. 商户本地生成一对 RSA 密钥:私钥(merchantRsaPri)自留,公钥(merchantRsaPub)上传至平台。
  2. 平台将平台公钥(platRsaPub)下发给商户。
  3. 此后:
    • 商户用 merchantRsaPri 对请求签名 → 平台用 merchantRsaPub 验签
    • 平台用平台私钥对响应签名 → 商户用 platRsaPub 验签

RSA 密钥交换示意图

使用 OpenSSL 生成 RSA 密钥

shell
# 1. 生成 2048 位私钥
openssl genrsa -out key.pem 2048

# 2. 转换为 PKCS8 格式(Java 使用此格式作为签名私钥)
openssl pkcs8 -topk8 -inform PEM -in key.pem -outform PEM -nocrypt

# 3. 导出对应公钥
openssl rsa -in key.pem -pubout -out public.pem

签名算法参数

参数
算法名称SHA256withRSA(Java)
OPENSSL_ALGO_SHA256(PHP)
密钥长度2048
密钥格式Java 使用 PKCS8
PHP 及其他语言使用 PKCS1
签名对象请求 Body 明文 JSON 字符串(加密前的业务请求报文)

签名与加密顺序

请求签名和 AES 加密使用同一份 Body 明文 JSON 字符串:

请求签名:Body 明文 JSON → 商户 RSA 私钥签名 → Header signature
请求加密:Body 明文 JSON → AES 加密 → aesBuffer

平台响应处理时,先使用 AES 密钥解密 data 字段,再使用平台公钥对解密后的响应明文 JSON 字符串进行验签:

响应解密:data 密文 → AES 解密 → 响应明文 JSON
响应验签:响应明文 JSON + Header signature → 平台公钥验签

注意

aesBuffer 和响应 data 的密文不作为 RSA 签名原文。生成签名和 AES 加密时,应复用同一份序列化后的 JSON 字符串,避免字段顺序、空值处理、日期格式或转义方式不一致导致验签失败。

签名 Demo 见 附录 - 测试信息及 Demo