签名工具
- 开放平台的应用管理体系,使用了公私钥的机制,商户可在开放平台 密钥管理 中设置应用的 接口加签方式 中为自身应用配置 公钥/公钥证书 防止数据篡改,以此来保障商户应用和开放平台交互的安全性。
名词解释
- 公钥:即 应用公钥(public_key),开发者通过工具自行生成的公钥信息。
- 私钥:即 应用私钥(private_key),开发者通过工具自行生成的私钥信息。
- 开放平台公钥:开发者在开放平台配置 应用公钥 后由开放平台生成,供开发者验证来自开放平台的异步或者同步信息签名。
签名算法说明
| 签名算法 | 标准签名算法 | 描述 |
|---|
| RSA | SHA256WithRSA | 强制要求 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 流,否则可能导致含中文参数的签名计算不正确
请求示例:
POST /v1/payments/open/api/pay HTTP/1.1
Host: api-open-cater.payloco.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"
}