一、签名方式#
RSA签名方案
签名内容产生规则:
1. 获取请求完整JSON报文,使用MD5计算出报文摘要值(全小写);
2. 将该摘要值按照指定的签名算法使用交易发送方的签名私钥进行签名,将签名值使用Base64转码得到签名串signature。
3. 将签名方式和签名值设置在http header中,并自定义如下对应属性:| 自定义Header key | 必须 | 描述 |
|---|
| Signature-Type | 是 | 签名方式:RSA |
| Signature-Data | 是 | 签名值RSA签名,见安全签名机制 Signature-Data = Base64(RSA(MD5(完整JSON报文))) |
| mch_id | 是 | 商户在平台系统中的唯一标识,如果是商户模式此参数必传 |
| sp_no | 可选 | 服务商编号,服务商接入模式下必须 |
| timestamp | 是 | 时间戳(yyyyMMddHHmmss) 例如20211110145022 |
| nonce | 是 | 随机字符串,至少为10位,有效期内防重复提交 |
二、签名规则#
可以直接通过平台线上申请,也可以线下直接颁发。mch_id是全局唯一的,每个mch_id将对应一个客
户。
2.加入timestamp(时间戳),以服务端当前时间为准,单位为ms,5分钟内数据有效时间戳的目的就是为了减轻DOS攻击。防止请求被拦截后一直尝试请求接口。服务器端设置时间戳
阀值,如果服务器时间减请求时间戳超过阀值,表示签名超时,接口调 用失败。
3.加入临时流水号nonce,至少为10位,有效期内防重复提交。随机值nonce主要是为了增加签名sign的多变性,也可以保护接口的的幂等性,相邻的两次请求
nonce不允许重复,如果重复则认为是重复提交,接口调用失败。
三、特殊字段加密#
针对API报文的部分字段,由于其信息敏感性,需要对该字段进行加密传输。由于RSA或国密算法,都需要申请证书,故我们约定同一报文的算法保持一致。| 报文Signature-Type | 签名算法 | 加密算法 |
|---|
| RSA | MD5withRSA | RSA |
RSA加密方案
1. 获取请求待加密字段明文;
2. 将明文使用交易发送方的RSA公钥进行加密,将加密值使用Base64转码得到密文,ciphertext-Data = Base64(RSA(plaintext))。四、基于RSA算法#
五、签名验签#
注意
签名请务必获取字符串验签,而非接收对象转字符串验签。由于业务迭代,部分通知可能新增字段,若企业通过对象验签会导致 签名不通过!
六、加密解密#
String text = "这是一条待加密明文";
System.out.println("明文:" + text);
String encodeText = RSAUtil.getInstance().encrypt(text), CommercialTenant.getPublickey());
System.out.println("密文:" + encodeText);
String decodeText = RSAUtil.getInstance().decrypt(encodeText), CommercialTenant.getPrivatekey());
System.out.println("解密后明文:" + decodeText);