ruby 银行对接证书的签名以及验签

最近项目要做在线支付,选择了一个银行要做对接,过了一遍文档,大体知道难点主要在签名和验签上,奈何银行提供的demo只有java版本的,原来对java接触的比较少,这次终于有机会研究研究java的代码了。然后改写成ruby方法。

demo里java的签名,验签方法。

签名主要是通过读取私钥,然后通过私钥对明文进行MD5withRSA的加密方法。
验签的话跟签名正好相反,通过读取公钥,然后对来判断是否跟通过公钥加密过的明文数据一样。

将jks证书容器转换成pem

1.将sert.jks转换为sert.p12(公钥文件是cer格式的,不用转换,ruby里面可以直接读取)

1
keytool -importkeystore -srckeystore sert.jks -destkeystore sert.p12 -srcstoretype jks -deststoretype pkcs12

2.将sert.p12转换为sert.pem

1
openssl pkcs12 -in sert.p12 -out sert.pem

改写完成的ruby方法

1.签名方法

1
2
3
4
5
6
def rsa_sign(rsa_string)
pri = OpenSSL::PKey::RSA.new File.read('sert.pem'), '111111'
sign = pri.sign('md5', rsa_string.encode("GBK"))
signature = sign.unpack('H*').first
return signature
end

2.验签方法

1
2
3
4
def rsa_verify(signature, verify_string)
certificate = OpenSSL::X509::Certificate.new File.read "paygate.cer"
certificate.public_key.verify('MD5', [signature].pack('H*'), verify_string.encode("GBK"))
end

总结,中间还是遇到了一些坑

1.encode和force_encoding

encdoing 用来查看字符串的编码信息。
force_encoding 用来修正字符串编码信息,注意是修正。
encode,encode! 用来转码字符串。

注意:force_encoding 方法只是改变了字符串对象的编码信息,并没有改变字符串对象实际存储的内容。
encode改变了编码信息同时也改变了字符串对象存储的内容
我就在这里浪费了很多时间,因为在参考了一个博客,里面是用的 force_encoding编码,所以签名一直不对。
参考链接

2 unpack和pack

pack模板字符串。参考链接。切记,生成签名的时候用了unpack模板字符串,验签的时候也要用pack,转回来。