Skip to content

授权 HMAC 验证

Genstore 向应用发送的所有请求都会携带 hmac 参数。您需要使用 HMAC-SHA256 对该参数进行验证,以确保请求来自 Genstore 且未被篡改。

本文档将介绍如何从请求中提取参数、生成签名并校验 HMAC 的完整流程。

验证流程概览

要验证请求的真实性,您需要:

  1. 从查询参数中移除 hmac
  2. 对剩余参数按字母顺序排序并拼接成字符串
  3. 使用应用的 Client secret 通过 HMAC-SHA256 生成签名
  4. 将生成的签名与请求中的 hmac 进行比对
    • 一致:请求有效
    • 不一致:拒绝请求

步骤一:移除 hmac 参数

以下为 Genstore 请求示例:

shop={shop}&shopId={shopId}&timestamp={timestamp}&hmac={hmac}

验证前,需要从查询参数中移除 hmac,得到:

shop={shop}&shopId={shopId}&timestamp={timestamp}

步骤二:对剩余参数排序并拼接

将所有非 hmac 的查询参数按 键名字母顺序 排序,并按以下格式拼接成字符串:

shop={shop}&shopId={shopId}&timestamp={timestamp}

确保:

  • 键与值之间使用 =
  • 参数之间使用 &
  • 不要 URL decode
  • 不要额外添加空格或换行

步骤三:使用 HMAC-SHA256 生成签名

使用应用的 Client secret 作为密钥,通过 HMAC-SHA256 对拼接后的参数字符串进行加密,并生成十六进制签名。

示例(Java):

java
String secret  = "client_secret";
String message = "shop={shop}&shopId={shopId}&timestamp={timestamp}";

Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] bytes = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));

生成的 bytes 需转为十六进制字符串作为最终签名。

步骤四:校验 hmac

将生成的十六进制签名与请求查询参数中的 hmac 值进行比对:

  • 一致 → 请求真实可信
  • 不一致 → 请求无效,可能被篡改,应拒绝处理

校验失败的常见原因

  • 参数顺序未排序或排序错误
  • URL decode 导致字符串变化
  • Client secret 使用错误
  • 参数拼接格式中包含多余空格
  • 将 hmac 本身包含在签名计算中