跳转至

回调签名

回调的签名

签名校验

商户收到的回调信息都带有HMAC-SHA256算法生成的签名, 签名内容在http header的 "Liquido-Signature" 字段。
header中除了签名内容本身,还包含签名算法和生成签名的时间戳, 结构如下:

algorithm=HmacSHA256,timestamp={{timestamp_in_seconds}},signature={{signature}}

商户可按照下面的步骤生成签名并验证:

  • 使用回调请求的原始http body作为payload.
  • 用如下格式生成签名内容: content = "payload={{payload}},timestamp={{current_timestamp_in_seconds}}".
  • 商户在授权接口中的client secret作为签名的秘钥 secret.
  • signature = HmacSHA256(content, secret)

Java的签名校验代码样例如下.

import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.codec.binary.Hex;


public class HmacSignUtils {
    private static final String HEADER_FORMAT_STRING = "algorithm=%s,timestamp=%s,signature=%s";

    private static final String CONTENT_FORMAT_STRING = "payload=%s,timestamp=%s";

    public static final String ALGORITHM = "HmacSHA256";

    public static final String SIGNATURE_HEADER_KEY = "Liquido-Signature";

    public boolean verifySignature(
            final String signature, 
            final String payload, 
            final String timestamp,
            final String secret
    ) throws NoSuchAlgorithmException, InvalidKeyException {
        final String content = String.format(CONTENT_FORMAT_STRING, payload, timestamp);
        return signature.equals(calculateSignature(content, secret));
    }

    private static String calculateSignature(final String content, final String secret)
            throws NoSuchAlgorithmException, InvalidKeyException {
        final Mac sha256Hmac = Mac.getInstance(ALGORITHM);
        final SecretKeySpec keySpec =
                new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), ALGORITHM);
        sha256Hmac.init(keySpec);
        final byte[] digest = sha256Hmac.doFinal(content.getBytes(StandardCharsets.UTF_8));
        return Hex.encodeHexString(digest);
    }

}
回到页面顶部