签名
签名
每次请求必须在 system.sign 携带签名。平台根据 appId 查找 appSecret 并按相同规则验签。
计算步骤
- 签名原始串(UTF-8):将
time、nonce、appSecret按键值对拼接,顺序为 time → nonce → appSecret,英文逗号分隔:
签名原始串 = time:{time},nonce:{nonce},appSecret:{appSecret}
appSecret 在 控制台 · 我的应用 · 应用信息 获取,仅用于服务端。
- 派生密钥
password:对appSecret做 SHA-256,结果转为小写十六进制:
password = LowerCase(Hex(SHA-256(appSecret)))
- 计算
sign:以password为密钥,对签名原始串做 HMAC-SHA256,再 Base64 编码:
sign = Base64(HMAC-SHA256(签名原始串, password))
时间戳与 nonce 约束见 调用约定(错误码 SN1002、SN1005)。
代码示例(Java)
import org.apache.commons.codec.digest.DigestUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.time.Instant;
import java.util.Base64;
import java.util.UUID;
Long time = Instant.now().getEpochSecond();
String nonce = UUID.randomUUID().toString();
String appSecret = "test123456789test123456789";
String SIGN_TEMPLATE = MessageFormat.format(
"time:{0},nonce:{1},appSecret:{2}", time.toString(), nonce, appSecret);
String password = DigestUtils.sha256Hex(appSecret).toLowerCase();
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(password.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] digest = mac.doFinal(SIGN_TEMPLATE.getBytes(StandardCharsets.UTF_8));
String sign = Base64.getEncoder().encodeToString(digest);
标准案例
用下列固定入参在本地试算;结果与案例一致即表示实现正确。
| 入参 | 值 |
|---|---|
| time | 1706511734 |
| nonce | f5a1ae2d-c09c-4d39-a744-83a5c2c653c2 |
| appSecret | test123456789test123456789 |
步骤 1 — 签名原始串:
time:1706511734,nonce:f5a1ae2d-c09c-4d39-a744-83a5c2c653c2,appSecret:test123456789test123456789
步骤 2 — password:
1f2da89b2fab404859f02bcc80e8521bc7a63af3e5b1da5318f7cf7c56836b09
步骤 3 — sign:
xjhCQBoJ9hRDsCjyDcHjtDNzRZ3ZJezcawsfWeiaoxU=
对应 system 示例:
{
"system": {
"ver": "1.0",
"appId": "lcdxxxxxxxxx",
"sign": "xjhCQBoJ9hRDsCjyDcHjtDNzRZ3ZJezcawsfWeiaoxU=",
"time": 1706511734,
"nonce": "f5a1ae2d-c09c-4d39-a744-83a5c2c653c2"
},
"id": "98a7a257-c4e4-4db3-a2d3-d97a3836b87c",
"params": {}
}