1、说明
一、说明:
1.如何请求
| 内容 | 备注 |
|---|---|
| 订单的创建、查询请求方式 | post,Content-Type: application/json |
| 回调 | post,Content-Type: application/json |
2. 请求头
| 参数 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| merchantNo | 是 | string | 商户号,由 平台 提供 |
| sign | 是 | string | 请求体的 的RSA签名 |
3. RSA 签名与验签算法
1. 签名流程
- 根据具体接口文档,构造请求参数,将请求参数格式化为 JSON 格式字符串(作为请求 Body);
- 使用商户自身的私钥(Private Key)对该 JSON 字符串进行 SHA256withRSA 签名;
- 将签名后的字节数组通过 Base64 编码后放入 HTTP Header 的 sign 字段中;
- 将商户号放入 HTTP Header 的 merchantNo 字段中,发起 HTTP POST 请求。
2. 验签流程
- 商户端请求平台:平台使用商户提供的公钥对 sign 与请求 Body 进行验签;
- 平台回调商户端:平台推送异步回调时,商户端需使用平台提供的公钥对 sign 与回调 Body 进行验签(注:验签时请注意忽略大小写差异)。
平台测试通道公钥:验签使用(正式公钥在商户后台-账户管理处查看)
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0HbxDzspzXumRRWHO9gnbIYHebR80RtRpPH20DtXsEJRGWVtmCnOi6NOAnHohZHcW1buSIf10GGdWBh8tpSqYCV0OzkTEhJ/3DPsmqIL50JxOTkLAfY0tWESjJlYGi7acnTmLmzFQH7ben1nmFhwuG5168cDpF4FLfvCFurbEG93x9fWPzE3mGOnM8TI3yI5yUYXzpZSxCcYG4DIFVSvhmCyiWN8Lj6FFd/cQLywsVOokA24QKC+k7EbG2vLktEM9gRVR344faQQ6rDucgMWiaUEojFOUKkj6AcSc2EFE9I4CUYzk52upGKWv/YtNj4AokjlQVWv1558JZInmVfQDHBNVrbgTnmcgQwSNWOTgV53NbRP6gu0bFdzfUMD7WheykreY5LMcfHZkoGMZirv3nM8m7XiazUE+GOnQLN/IHaF8maumWFWTCn5rnLXn8S5VVRS5HXND0cWNB/ooSDqmgzmA6OzBgV97fp6EqhvXny3QQy87dNEFL2n+RCDptGmtAPV7BD5dc5AVqkQ5nG1hA/kCWIaTsG6/dEfB4dg6c3DDd+zjML+5EduBkfvcBKjTcWR2oUh9UCkOaeDVB+VLhuLRZ2tsuSUJJWWfj1npevljegjCMBLB4UgvRMgSF67wQ/JDp87qab1cAlezvJoTHQr2ZjASD8WB5OpFEzhbV8CAwEAAQ==
公私钥生成工具链接(选择 1024 位、2048 位、4096 位 / 格式 PKCS#8):https://www.bejson.com/enc/rsa/#18
去换行工具链接(用这个链接去除一下换行再上传):http://www.wuqianling.top/software/notepad/compress.html
生成与配置说明:
生成密钥对:使用密钥生成工具生成密钥对,长度必须是 1024bit、2048bit 或 4096bit,格式必须是 PKCS#8。
去除换行并上传公钥:将生成密钥对中的公钥,去除换行后复制,上传到商户后台。不要包含 -----BEGIN KEY----- 与 -----END KEY-----。
保管私钥:公钥上传完成后,请妥善保管私钥,切勿外泄。
技术支持:如对接过程遇到加解密、签名异常等问题,可以发送请求参数至对接群里,并艾特我们客服或者技术人员。
回调验签说明:对于平台回调签名,请使用平台公钥进行解密验证,切勿使用商户公钥(您自行生成的公钥)。
java 代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class SignUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(SignUtil.class);
public static boolean checkSign(String param, String sign, String publicKey) {
try {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey))));
signature.update(param.getBytes());
return signature.verify(Base64.getDecoder().decode(sign));
} catch (Exception e) {
LOGGER.error("Sign校验错误 :", e);
}
return false;
}
public static String sign(String param, String privateKey) {
try {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey))));
signature.update(param.getBytes());
byte[] bytes = signature.sign();
return Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
LOGGER.error("Sign签名错误 :", e);
}
return null;
}
Map<String, Object> map = new HashMap<>();
map.put("timestamp", "timestamp");
map.put("merchantOrderNo", "merchantOrderNo");
String body = gson.toJson(map);
String sign = SignUtil.sign(body, PrivateKey);
HttpResponse<String> stringHttpResponse = Unirest.post(url)
.header("Content-Type", "application/json; charset=utf-8")
.header("merchantNo", "merchantNo")
.header("sign", sign)
.body(body)
.asString();
public static void main(String[] args) throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096);
KeyPair keyPair = keyPairGenerator.genKeyPair();
PublicKey publicKey = keyPair.getPublic();
byte[] publicKeyBytes = publicKey.getEncoded();
String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKeyBytes);
System.out.println(publicKeyBase64);
PrivateKey privateKey = keyPair.getPrivate();
byte[] privateKeyBytes = privateKey.getEncoded();
String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKeyBytes);
System.out.println(privateKeyBase64);
String json = "qwer12345";
String sign = SignUtil.sign(json, privateKeyBase64);
System.out.println(sign);
boolean b = SignUtil.checkSign(json, sign, publicKeyBase64);
System.out.println(b);
}