签名
签名
抄自 开发规范 第 4 节。appSecret 不能放进客户端安装包或公开仓库。
参数顺序
构造待签名字符串:把 time、nonce、appSecret 按 time → nonce → appSecret 拼成键值对,英文逗号分隔(UTF-8):
signing source string = time:{time},nonce:{nonce},appSecret:{appSecret}
在 控制台 → 我的应用 → 应用信息 获取
appSecret。
time 和 nonce 必须与写入 system 的值相同。请求体结构见 请求约定。
密钥边界
appSecret 只在服务端用来派生 password 和 sign。不要把 appSecret 放进 params。不要把示例 sign 用到生产。
哈希与签名
- 派生签名密钥
password:对appSecret做 SHA-256,再转成小写十六进制:
password = LowerCase(Hex(SHA-256(appSecret)))
- 计算
sign:用password作密钥,对源串做 HMAC-SHA256,再 Base64:
sign = Base64(HMAC-SHA256(signing source string, password))
示例代码(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;
/**
* 示例:计算 sign
*/
// 1. 当前 UTC 时间戳(秒)
Long time = Instant.now().getEpochSecond();
// 2. 随机 nonce
String nonce = UUID.randomUUID().toString();
// 3. 请使用控制台中的真实 appSecret;下列仅为示例。
String appSecret = "test123456789test123456789";
// 4. 构造待签名字符串
String SIGN_TEMPLATE = MessageFormat.format(
"time:{0},nonce:{1},appSecret:{2}", time.toString(), nonce, appSecret);
// 5. Derive password = LowerCase(Hex(SHA-256(appSecret)))
String password = DigestUtils.sha256Hex(appSecret).toLowerCase();
// 6. Calculate sign = Base64(HMAC-SHA256(SIGN_TEMPLATE, password))
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=
常见签名失败
| 现象 | 规范已经写明的 |
|---|---|
SN1005 | 5 分钟内重复使用 nonce |
| 时间被拒 | system.time 是 UTC 秒;时差不能超过 5 分钟 |
| 与验算用例不一致 | 字段顺序必须是 time → nonce → appSecret;password 是小写十六进制 SHA-256;HMAC 密钥是该 password 字符串 |
抄了示例 sign | 每次请求重新计算 |
其它 result.code:返回码。
