公司目前使用的支付宝的接口方式是快捷支付,这种接口使用的是 rsa 加密,网上貌似没有现成的 gem 可用,这个接口的 sdk 有 java c# php 的范例代码,php 和 java 的方式完全不同,java 用的是字符串,php 用的是秘钥文件,研究下来发现 ruby 应该是与 php 相似,经过一番折腾,初步把 rsa 加密搞定(但不知道是否正确)然后调用这个接口返回的结果是,系统繁忙,彻底无语了。 貌似这个坑跨不过去了。同事给的建议是把 java 的代码封装成一个命令行程序,再在 ruby 中调用这个命令行程序。 各位大侠谁有其他好的建议,或者你们谁用 ruby 搞过这个
代码很简单,就是 rsa 加密
def rsa_sign(rsa_string)
pri = OpenSSL::PKey::RSA.new(alipay.private_key)
sign = pri.sign('sha1', rsa_string.force_encoding("utf-8"))
signature = CGI.escape(Base64.encode64(sign))
return signature
end
def create_sign_string(sign_params)
sign_keys = sign_params.keys
origin_string = sign_keys.inject(''){|s, key|
if key.to_s == 'notify_url'
s += %Q{#{key}="#{URI.encode(sign_params[key], Regexp.new(/:\/\//))}"&}
else
s += %Q{#{key}="#{sign_params[key]}"&}
end
}
return origin_string
end
之前在 alipay 这个 gem 中实现过 rsa 验证的,不过没有实现 rsa 加密,代码应该也不相差太多吧,可以看看我这个 PR https://github.com/chloerei/alipay/pull/10/files#diff-2
alipay 没有 rsa 加密部分,我们项目现有的 java 代码是可以正确的,但是 java 和 ruby 对 rsa 加密的机制好像是不一样的,所以还不好把 java 部分的代码照抄过来,而 ruby 的 rsa 加密我尝试了好多次,返回的结果不是服务器繁忙就是参数错误,根据网上的反馈,估计是私钥错问题了,但就是不知道错了什么问题。
我是直接用同样的输入比较输出,不知道这种方法是不是正确的 java 是首先生成 private pem,然后生成 pkcs8 格式,然后把其中的字符串取出来当作 key 而 ruby 是直接使用 private.pem。 现在看来,结果是不一样的(前面倒是一样), dUo8k35ESagz5x7IRKnA92L7GlLBs8T4HtwlsAm7JLxEtWg9FrR683h3OlcJo2liYUXUQHL%2BvvPLuuV40yryOEXu8%2F54nNdI9vDbU27vNF8DqAWi9NPgHek3wmPRxDA11Kqw%2F3c14Dw1MPreUgieZp7zgS7J3iuGtP6sa4%2BTAAY%3D
dUo8k35ESagz5x7IRKnA92L7GlLBs8T4HtwlsAm7JLxEtWg9FrR683h3OlcJ%0Ao2liYUXUQHL%2BvvPLuuV40yryOEXu8%2F54nNdI9vDbU27vNF8DqAWi9NPgHek3%0AwmPRxDA11Kqw%2F3c14Dw1MPreUgieZp7zgS7J3iuGtP6sa4%2BTAAY%3D%0A
朋友你这个问题解决了没,我用了你的代码,也是不行
def rsa_sign(rsa_string) pri = OpenSSL::PKey::RSA.new(alipay.private_key) sign = pri.sign('sha1', rsa_string.force_encoding("utf-8")) signature = CGI.escape(Base64.encode64(sign)) return signature end