JAVA 代码
/**
*
* 将通过Base64编码后的String类型的私钥字符串转换为PrivateKey对象
*
* @param strPriKey Base64编码后的String类型的私钥字符串
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @since 10.15
*/
public static PrivateKey getPrivateKey(String strPriKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(strPriKey));
KeyFactory keyFactory = KeyFactory.getInstance(RSA);
PrivateKey priKey = keyFactory.generatePrivate(priKeySpec);
return priKey;
}
然后进行 RSA 签名
/**
*
* RSA签名:
*
* @param data 请求原文
* @param prik 私钥
* @return 签名值
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws SignatureException
* @since 10.15
*/
public static byte[] sign(byte[] data, PrivateKey prik) throws NoSuchAlgorithmException, InvalidKeyException,
SignatureException {
Signature signature = Signature.getInstance(SHA1_WITH_RSA);
signature.initSign(prik);
signature.update(data);
return signature.sign();
}
/**
*
* RSA签名
*
* @param data 请求原文
* @param prik 私钥
* @return
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws SignatureException
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static String sign(String data, PrivateKey prik) throws InvalidKeyException, NoSuchAlgorithmException,
SignatureException {
return Base64.encodeBase64String(sign(data.getBytes(), prik)).trim();
}
方法实现
// (1).获取加签私钥
PrivateKey prik = RSAUtil.getPrivateKey(商户私钥字符串);
// (2).排除不参与加签的字段。生成摘要明文 params = Digest.treeMap(params, "sign_type","signkey_index");
String digestData = Digest.mapToString(params);
// (3).对摘要明文进行MD5摘要 digestData = MD5.digest(digestData, "utf-8");
// (4).传入摘要密文和私钥,进行加签
String sign = RSAUtil.sign(digestData, prik);
// (5). 进行urlEncode编码
sign = URLEncoder.encode(sign, "utf-8");
// (6). 将加签后的sign放入请求参数中
params.put("sign", sign);
试着用 ruby 的方式写出来
key = File.read('lib/suning_cert/rsa_private_key.pem')
rsa = OpenSSL::PKey::RSA.new(key)
sign = (Digest::MD5.hexdigest data).upcase
sign = Base64.strict_encode64(rsa.sign('sha1', data.force_encoding("utf-8")))
最后得到的签名没有通过平台的验签。是需要把私钥转化为 PrivateKey 对象么,我不太清楚 java 怎么做的。就不知道如何改写了。。。