Skip to main content

Sign Rule

  • 更新时间:2022-07-05 13:50:33

简介

  • 开放平台的应用管理体系,使用了公私钥的机制,商户可在开放平台 密钥管理 中设置应用的 接口加签方式 中为自身应用配置 公钥/公钥证书 防止数据篡改,以此来保障商户应用和开放平台交互的安全性。

名词解释

  1. 公钥:即 应用公钥(public_key),开发者通过工具自行生成的公钥信息。
  2. 私钥:即 应用私钥(private_key),开发者通过工具自行生成的私钥信息。
  3. 开放平台公钥:开发者在开放平台配置 应用公钥 后由开放平台生成,供开发者验证来自开放平台的异步或者同步信息签名。

签名算法说明

签名算法标准签名算法描述
RSASHA256WithRSA强制要求 RSA 密钥的长度至少为 2048。

功能说明

  • 如果不清楚接口调用方法,请先查看文档 接口调用约定。
  • 调用每个接口都需要携带签名,服务端会根据请求参数,对签名进行校验,签名不合法的请求将会被拒绝,目的主要是
    • 服务商侧&开放平台侧校验每次请求参数的数据完整性
    • 服务商侧&开放平台侧验证请求者的身份

签名计算

JAVA签名参考代码

     生成私钥
    /**
     * 获取私钥
     *
     * @param privateKey 私钥字符串
     * @return
     */
    public static PrivateKey getPrivateKey(String privateKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
        return keyFactory.generatePrivate(keySpec);
    }
    /**
     * 签名
     *
     * @param data 待签名数据
     * @param privateKey 私钥
     * @return 签名
     */
    public static String sign(String data, PrivateKey privateKey) throws Exception {

       
        byte[] keyBytes = privateKey.getEncoded();
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey key = keyFactory.generatePrivate(keySpec);
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(key);
        signature.update(data.getBytes("UTF-8"));
        return new String(Base64.encodeBase64(signature.sign()));
    }

JAVA验证签名参考代码

	/* 获取公钥
     *
     * @param publicKey 公钥字符串
     * @return
     */
    public static PublicKey getPublicKey(String publicKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
        return keyFactory.generatePublic(keySpec);
    }
     /**
     * 验签
     *
     * @param srcData 原始字符串
     * @param publicKey 公钥
     * @param sign 签名
     * @return 是否验签通过
     */
    public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {
        byte[] keyBytes = publicKey.getEncoded();
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey key = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(key);
        signature.update(srcData.getBytes("UTF-8"));
        return signature.verify(Base64.decodeBase64(sign.getBytes()));
    }
如果您使用其他语言,可以参考代码自行实现。

签名算法:

1 参与签名的字段:请求的JSON报文全部参与签名。
2 签名算法:本支付系统的签名算法采用SHA256withRSA算法。

注意:

计算 SHA256withRSA 签名时,需要以 utf-8 的编码转换 byte 流,否则可能导致含中文参数的签名计算不正确

请求示例:

request
POST /v1/payments/open/api/pay HTTP/1.1
Host: api-open-cater.payallglobal.com
signature: M+CSWJPVOxHHyT2K85VzGifLx7UrF2LYA/V9ATFQFa75WvCwZ3T0mcBIcptn/s+T/i/X2FElVSpL0S7WMiNU70Lg+DeNtgic+4BfwVGoMhX5Mq0pkrriruArZHI58/5bs1S98SFvjciiBpZnN3xziuwHWRoW6yO3anp1/XKTbVc=
Content-Type: application/json;charset=utf-8

{
    "accessType":"s2s",
    "carrierId":"111",
    "charset":"utf-8",
    "currency":"HKD",
    "dcc":"",
    "deviceChannel":"brower",
    "goodsName":"跨境商品",
    "merchantId":"2001000000002036",
    "merchantOrderId":"20220726094400",
    "merchantOrderTime":1657778971313,
    "payMode":"QRCODE",
    "merchantRegion":"",
    "redirectUrl":"http://192.168.11.170:9063/notify/1/success",
    "notifyUrl":"http://192.168.11.170:9063/notify/1/success",
    "reqReserved":"",
    "reserved":"",
    "signType":"RSA",
    "transAmt":"3.01",
    "transChannel":"WEIXIN",
    "transTimeout":30,
    "transType":"PAYS",
    "version":"2.0.0"
}