#

SUD

简要描述

回调签名验证,可以基于签名对Sud服务端的回调请求进行合法性验证(可选)

1. 准备

应用id(app_id), 应用密钥(app_secret)

2. 构造签名串

  • 2.1 首先,服务端从回调请求 Http Header 中获取签名信息。
- HTTP请求头 Sud-AppId: 应用id
- HTTP请求头 Sud-Timestamp: 回调时间戳
- HTTP请求头 Sud-Nonce: 随机字符串
- HTTP请求头 Sud-Signature: 签名值
  • 2.2 签名串一共有四行,每一行对应一个参数。行尾以 \n 结束,包括最后一行。
应用ID\n
回调时间戳\n
随机字符串\n
请求body\n
  • 2.3 签名串示例:
1461564080052506636
146634788974
keVJLJTItd1VBtGT
{"app_id": "1461564080052506238","mg_id": "1461227817776713818","room_id": "9009","round_id": "ce56b6lzi1a7-cehorlmy01pq-ckmfkba10iv7","currency_amount": "2", "timestamp": 1654079242000}

3. 计算签名值并验签

使用应用密钥(app_secret)对签名串进行 HmacSHA1算法加密,生成对应的签名值,并与HTTP请求头Sud-Signuture的值比较

  • Java示例代码:

/**
 * 校验签名
 *
 * @param request     请求体
 * @param requestBody 请求内容,为保证发送方与接收方的数据一致,建议在拦截器里取对应值
 * @return true: 验签成功, false: 验签失败
 */
public boolean verifySignature(HttpServletRequest request, String requestBody) {
        // SudAppId
        String sudAppId = request.getHeader("Sud-AppId");
        // SudTimestamp
        String sudTimestamp = request.getHeader("Sud-Timestamp");
        // SudNonce
        String sudNonce = request.getHeader("Sud-Nonce");
        // SudSignature
        String sudSignature = request.getHeader("Sud-Signature");
        // 请求body (需保证发送方与接收方的数据一致,建议在拦截器里取对应值)
        String body = requestBody;

        // 构造签名串
        String signContent = String.format("%s\n%s\n%s\n%s\n", sudAppId, sudTimestamp, sudNonce, body);

        // 计算签名值
        String appSecret = "";
        HMac hMac = new HMac(HmacAlgorithm.HmacSHA1, appSecret.getBytes());
        String signature = hMac.digestHex(signContent);

        // 比较签名值 true: 验签成功, false: 验签失败
        return sudSignature.equals(signature);
        }
  • Node示例代码:

const Crypto = require('crypto');

function verifySignature(request) {
    // SudAppId
    let sudAppId = request.headers["Sud-AppId"];
    // SudTimestamp
    let sudTimestamp = request.headers["Sud-Timestamp"];
    // SudNonce
    let sudNonce = request.headers["Sud-Nonce"];
    // SudSignature
    let sudSignature = request.headers["Sud-Signature"];
    // 请求body (需保证发送方与接收方的数据一致,建议在拦截器里取对应值)
    let body = request.body;

    // 构造签名串
    let signContent := sudAppId + '\n' + sudTimestamp + '\n' + sudNonce + '\n' + JSON.stringify(body) + '\n';

    // 计算签名值
    let appSecret = '';
    let hmac = Crypto.createHmac('sha1', appSecret);
    let signature = hmac.update(signContent).digest('hex');

    // 比较签名值 true: 验签成功, false: 验签失败
    return sudSignature == signature;
}
  • Go示例代码:

import (
    "crypto/hmac"
    "crypto/sha1"
    "fmt"
    "github.com/valyala/fasthttp"
)
func verifySignature(ctx *fasthttp.RequestCtx) bool {
    // SudAppId
    sudAppId := ctx.Request.Header.Peek("Sud-AppId")
    // SudTimestamp
    sudTimestamp := ctx.Request.Header.Peek("Sud-Timestamp")
    // SudNonce
    sudNonce := ctx.Request.Header.Peek("Sud-Nonce")
    // SudSignature
    sudSignature := ctx.Request.Header.Peek("Sud-Signature")
    // 请求body (需保证发送方与接收方的数据一致,建议在拦截器里取对应值)
    body := ctx.Request.Body()

    // 构造签名串
    signContent := fmt.Sprintf("%s\n%s\n%s\n%s\n", sudAppId, sudTimestamp, sudNonce, string(body))

    // 计算签名值
    appSecret := ""
    mac := hmac.New(sha1.New, []byte(appSecret))
    mac.Write([]byte(signContent))
    signature := hex.EncodeToString(mac.Sum(nil))

    // 比较签名值 true: 验签成功, false: 验签失败
    return sudSignature == signature
}

results matching ""

    No results matching ""