Ruby Java 的 RSA 加密算法规则如何用 Ruby 改写呢?

a4652097 · 2017年12月11日 · 最后由 luikore 回复于 2017年12月13日 · 2472 次阅读

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 怎么做的。就不知道如何改写了。。。

你可以参考这里... https://ruby-china.org/topics/2267#reply-20430

不过现在 OpenSSL 支持 PKCS#8 转换了,或者直接调用命令行 openssl pkcs8 转换下 key 再交给 Ruby 也可以

2 楼 已删除
luikore 回复

是要把目前我的私钥匙转化为PKCS#8格式吗,求指导

a4652097 回复

是,那段代码做的就是这个事

需要 登录 后方可回复, 如果你还没有账号请 注册新账号