VandosPay Docs

签名计算

请求与响应签名规则与 Java 参考实现

签名算法

本系统使用 RSA 签名,算法名为 SHA512withRSA。计算过程分两步:

  1. 先对拼接后的签名原文做 SHA-512,得到 64 字节摘要 signData。
  2. 再使用 SHA512withRSA 对 signData 做 RSA 签名,最后对签名结果做 Base64 编码。

签名原文

请求

raw      = String(timestamp) + randomString + payload
signData = SHA512(utf8(raw))
sign     = Base64(RSA_sign_SHA512withRSA(clientPrivateKey, signData))

响应

raw      = timestamp + randomString + status + payload
signData = SHA512(utf8(raw))
sign     = Base64(RSA_sign_SHA512withRSA(platformPrivateKey, signData))

拼接规则:

  • timestamp 使用报文中的原值,请求为毫秒时间戳,响应为响应报文字段值。
  • randomString 使用报文中的随机字符串。
  • payload 使用已经 AES 加密并 Base64 编码后的 payload 字符串。
  • 各字段直接连接,不加分隔符、不做 URL 编码、不套 JSON。
  • 请求由接入方私钥签名,平台用接入方公钥验签;响应由平台私钥签名,接入方用平台公钥验签。

Java 参考实现

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.Base64;

public final class MessageSigner {

    public static String signRequest(String timestamp, String randomString, String payload,
                                     PrivateKey privateKey) throws Exception {
        return sign(timestamp + randomString + payload, privateKey);
    }

    public static boolean verifyResponse(String timestamp, String randomString, String status,
                                         String payload, String sign,
                                         PublicKey platformPublicKey) throws Exception {
        byte[] signData = sha512(timestamp + randomString + status + payload);

        Signature signature = Signature.getInstance("SHA512withRSA");
        signature.initVerify(platformPublicKey);
        signature.update(signData);
        return signature.verify(Base64.getDecoder().decode(sign));
    }

    private static String sign(String raw, PrivateKey privateKey) throws Exception {
        byte[] signData = sha512(raw);

        Signature signature = Signature.getInstance("SHA512withRSA");
        signature.initSign(privateKey);
        signature.update(signData);
        return Base64.getEncoder().encodeToString(signature.sign());
    }

    private static byte[] sha512(String raw) throws Exception {
        return MessageDigest.getInstance("SHA-512")
                .digest(raw.getBytes(StandardCharsets.UTF_8));
    }
}

signData 是 SHA-512 计算后的字节,请按示例把它作为 Signature.update 的输入,而不是直接传 timestamp + randomString + payload 字符串。

本页目录