以前工做主要使用C/C++与银行/第三方支付对接,但C/C++没法知足客户”当天给协议明天实盘上载“的开发速度以及现公司一些特殊状况,因此决定用go来尝试实现。基本的框架已经按照原来C/C++非阻塞框架实现一次,内部涉及加密方式也用go从新实现一遍,但一个数字证书加密的方式着实坑爹了一把,同时这个问题,也看到了openssl的命名混乱。html
关于这个加密方式的描述是:发送方用私钥进行rsa加密,接受方使用公钥进行rsa解密。看到这样的加密方式描述,感受和本身的理解是有点不同,不知道是否是本身对这方面了解不够深刻,本身的理解是(以前使用过的加密方式):公钥是公开的,私钥是本身保存的,用私钥对数据进行签名,用公钥验证签名。感受画风不同,翻查一下openssl,的确也是存在这样的函数:
RSA_private_encrypt
和RSA_public_decrypt
,参考文档。用openssl很容易就实现这样一个加密解密。但用纯go语言实现,不可能再用cgo来调用c函数,翻查一下go的文档,存在在相似的函数(crypt/rsa
):
func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error)
和func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error)
。但仔细看,这里是使用公钥进行加密,使用私钥进行解密,和描述恰好相反。除了这两个涉及公私钥加密的函数外,彷佛在go里面找不到其余相似的函数了。git
在google(*lanttern)里面,可以搜索到的答案彷佛很少,最后在stackoverflow找到结果:Encrypt message with RSA private key (as in OpenSSL's RSA_private_encrypt。一哥们手工搞定,其代码放在goplaygound。看了一下代码,若是不是对go内部的数据结构很是熟悉,并且对rsa机制很是清楚,很难写出正常代码。难道go就没有现成的代码完成这个功能?后面,有人就说,这是什么狗屁加密,压根就是一rsa签名,就用crypt/rsa
里面,func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error)
实现的。尼玛的,测试结果还真是同样。后来,回头看一下openssl里面的参考文档说明,These functions handle RSA signatures at a low level.,这就是签名啊,既然是签名,为什么命名encrypt/decrypt**?是否是由于命名问题,广为传播为私钥"加密"公钥"解密"呢?github
go不知道是否是受不了这样私钥"加密"公钥"解密"这种混乱的说法,不像其余语言同样提供相似的函数呢?至于公钥"解密",网上搜索不到满意答案,不过,既然私钥"加密"是rsa签名,那么公钥"解密"那么应该就是验证签名了。既然网上找不到满意的答案,那么只能修改一下go的func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error
函数。证明,这个想法是可行的。用openssl加密的数据,能够解密,加密的数据同时能够被openssl解密。golang
相关代码:https://github.com/buf1024/golib/tree/master/crypt 只简单导出PrivateEncrypt
和PublicDecrypt
两个函数。数据结构
最后,openssl的确存在一些很是混乱的命名方式,而其余语言/库,妥协这种混乱状况,那么混乱看起来即变为广泛。如不是很是熟悉,那么到一个再也不妥协这种混乱时,那么及其容易使本身混乱啊。框架