1.
获取所有post 内容,不包括字节类型参数,如文件、字节流,剔除 sign 字段以及值为空的参数;
2.
按照第一个字符的键值 ASCII 码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值 ASCII 码递增排序,以此类推;
3.
将排序后的参数与其对应值,组合成 JSON 格式String字符串,此时生成的字符串为待签名字符串。
4.
使用各自语言对应的 SHA256WithRSA(对应 sign_type 为 RSA2)签名函数利用私钥对签名字符串进行签名,并进行 Base64 编码后赋值给 sign 参数。
示例代码#
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
已经改进为可分段加密和解密
*/
@Slf4j
public class SignUtil {加密算法RSA
*/
private static final String KEY_ALGORITHM = "RSA";
MD5withRSA SHA1WithRSA SHA256WithRSA
*/
private static final String SIGNATURE_ALGORITHM = "SHA256WithRSA";
RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
编码
*/
private static final String CHARSET_NAME = "UTF-8";
@return
*/
public static String sign(String data, String privateKey) {
String sign = null;
try {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey priKey = keyFactory.generatePrivate(keySpec);
Signature si = Signature.getInstance(SIGNATURE_ALGORITHM);
si.initSign(priKey);
si.update(data.getBytes(CHARSET_NAME));
byte [] dataSign = si.sign();
sign = Base64.encode(dataSign);
} catch (Exception e) {
log.error("签名错误信息:{}",e.getMessage());
e.printStackTrace();
sign = null;
}
return sign;
}
@return
*/
public static boolean verify(String data, String sign, String publicKey) {
boolean result = false;
try {
Signature ver = Signature.getInstance(SIGNATURE_ALGORITHM);
KeyFactory keyFac = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey puk = keyFac.generatePublic(new X509EncodedKeySpec(Base64.decode(publicKey)));
ver.initVerify(puk);
ver.update(data.getBytes(CHARSET_NAME));
result = ver.verify(Base64.decode(sign));
} catch (Exception e) {
log.error("验签错误信息:{}",e.getMessage());
e.printStackTrace();
result = false;
}
return result;
}
数据处理过程#
创建转账任务请求参数处理示例(收款人明细[payTrans]参数不参与签名)#
请求参数(需要加签的参数,不包含不参与签名字段):{"importBatchNo":"1728726646977","merchantId":32,"timestamp":1728726646977,"totalCount":2,"totalTransAmount":"2"}
{"importBatchNo":"1728726646977","merchantId":32,"timestamp":1728726646977,"totalCount":2,"totalTransAmount":"2"}
Vz4+l83I1VCU0uRzhrcATOLs7uP4AHXOjRwkTak3JnY56tzYlU33lq+qxuNswLo5OnVu8pEfFBVGv+uY+VtyoZTCMjsOVUs0tdo5T5qKGIDY9v4Dfjn9SBMyifGKTq0Or0BUZnflICGiyjkf5Omh9Pg/DJq3ny2Zlb7WqKe+qroFm8GmQbNau9OdJvtsTehRiWUWqzDn9e+85YbmexH1wlRmNcSJkz2NmLr1Da8DNtYWLOOqJuCucn78bGl5CVwpITOHg2U1XbJY0epKe5LG5E7Kz/rgEvsAK4VXhsjYfMBGXOi55WKNTKfEI+km4/PnM2L3cDnsljL0BMAlA7JXAA==