和某行对接的时候,使用的加密算法
首先是需要哪种加密算法 ,这次使用的算法是 RSA2048withSHA256 PKCS#1 Padding
之前也没有写过类似这种的东西,查了一下,针对RSA2048算法,主要是需要先生成一对公私钥,私钥用来加密,公钥用来解密。 但是,需要先把对应的参数,进行SHA256进行加密。这就比较烦了,搞了半天,也不知道啥是RSA2048withSHA256 PKCS#1 Padding。 再查发现,就是生成密钥的格式,网上也有很多类似的工具,大家自行百度即可。
搞到了工具,那就开始搞吧,先按要求排序,需要的格式为 key1=val1&key2=val2& 自己抄的方法,方法如下:
/**
* 生成签名. 注意。
*
* @param dataParam 待签名数据
* @param merkey API密钥
* @param signType 签名方式
* @param generateType 以哪种格式进行加签验签,返回哪种格式
* @return 签名
*/
public static String generateSignature(final Map<String, Object> dataParam, String merkey, PayConstant.CmbSignType signType, String generateType) throws Exception {
logger.info("传入的需要加签的map:[{}]", dataParam);
logger.info("传入的需要加签的merkey:[{}]", merkey);
Set<String> keySet = dataParam.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder strToSign = new StringBuilder();
for (String k : keyArray) {
// 一般情况下参数值为空,则不参与签名 . 但不需要签名,所以此处可以不做判断,(dataParam.get(k).trim().length() >= 0)
strToSign.append(k).append("=").append(dataParam.get(k)).append("&");
}
//按指定签名算法进行运算。假设待签名字符串为strToSign,商户密钥为merkey,算法为sha256,对strToSign&merkey进行sha256签名
logger.info("拼接完成之后的待加签的字符串[{}]", strToSign);
if (PayConstant.CmbSignType.SHA256.equals(signType)) {
if (generateType.equals(GENERATE_ONLY_256HASH)){
return generateOnlyHash256(strToSign.toString());
}else if (generateType.equals(GENERATE_256HASH_AND_TOUPPER)){
return generate256HashAndChangeByteArrayHex(strToSign.toString());
}
// 默认进行sha256 签名运算
return generate256HashAndChangeByteArrayHex(strToSign.toString());
} else {
throw new Exception(String.format("Invalid sign_type: %s", signType));
}
}
在进行运算的时候,根据要求的不同,对其进行特殊的运算,有的需要转十六进制各种的,下面是其中的一个SHA256的方法:
/**
* 利用Apache的工具类实现SHA-256加密
* 所需jar包下載 http://pan.baidu.com/s/1nuKxYGh
*
* @param str 加密后的报文
* @return 把传进来的字符串,进行先SHA256算法运算,在转换成数组,在进行十六进制运算,最后在进行字母转大写
*/
public static String generate256HashAndChangeByteArrayHex(String str) {
MessageDigest messageDigest;
String encdeStr = "";
try {
messageDigest = MessageDigest.getInstance("SHA-256");
byte[] hash = messageDigest.digest(str.getBytes("GBK"));
//把hash进行16进制计算
encdeStr = Hex.encodeHexString(hash);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
logger.error("对字符串进行加密算法出现错误,加密算法类型为SHA-256,只生成Hash值,对其取数组时候,并转换十六进制,最后转大写,请检查加密算法");
e.printStackTrace();
}
logger.info("加密完的字符串[{}]",encdeStr.toUpperCase());
return encdeStr.toUpperCase();
}