回调签名
回调的签名
签名校验
商户收到的回调信息都带有HMAC-SHA256算法生成的签名, 签名内容在http header的 "Liquido-Signature" 字段。
header中除了签名内容本身,还包含签名算法和生成签名的时间戳, 结构如下:
商户可按照下面的步骤生成签名并验证:
- 使用回调请求的原始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);
}
}