在加解密过程中,使用openssl生产密钥。执行如下操作:
创建私钥 openssl genrsa -out private.pem 1024 //密钥长度,1024觉得不够安全的话可以用2048,但是代价也相应增大 创建公钥 openssl rsa -in private.pem -pubout -out public.pem // 这样便生产了密钥。一般地,各个语言也会提供API,用于生成密钥。在Go中,可以查看encoding/pem包和crypto/x509包。
加密解密这块,涉及到很多标准
Go RSA加密rsa加解密, 必须会去查crypto/ras这个包
Package rsa implements RSA encryption as specified in PKCS#1.这是该包的说明:实现RSA加密技术,基于PKCS#1规范。
对于什么是PKCS#1,可以查阅相关资料。PKCS(公钥密码标准),而#1就是RSA的标准。可以查看:PKCS系列简介
从该包中函数的名称,可以看到有两对加解密的函数。
EncryptOAEP和DecryptOAEP EncryptPKCS1v15和DecryptPKCS1v15这称作加密方案,详细可以查看,PKCS #1 v2.1 RSA 算法标准
可见,当与其他语言交互时,需要确定好使用哪种方案。
PublicKey和PrivateKey两个类型分别代表公钥和私钥,关于这两个类型中成员该怎么设置,这涉及到RSA加密算法,本文中,这两个类型的实例通过解析文章开头生成的密钥得到。
2 . 解析密钥得到PublicKey和PrivateKey的实例
这个过程,我也是花了好些时间(主要对各种加密的各种东东不熟):怎么将openssl生成的密钥文件解析到公钥和私钥实例呢?
在encoding/pem包中,看到了—–BEGIN Type—–这样的字样,这正好和openssl生成的密钥形式差不多,那就试试。
在该包中,一个block代表的是PEM编码的结构,关于PEM,请查阅相关资料。我们要解析密钥,当然用Decode方法:
/* func Decode(data []byte) (p *Block, rest []byte) */这样便得到了一个Block的实例(指针)。
解析来看crypto/x509。为什么是x509呢?这又涉及到一堆概念。先不管这些,我也是看encoding和crypto这两个包的子包摸索出来的。
在x509包中,有一个函数:
func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error)从该函数的说明:ParsePKIXPublicKey parses a DER encoded public key. These values are typically found in PEM blocks with “BEGIN PUBLIC KEY”。可见这就是解析PublicKey的。另外,这里说到了PEM,可以上面的encoding/pem对了。
而解析私钥的,有好几个方法,从上面的介绍,我们知道,RSA是PKCS#1,刚好有一个方法:
func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error)返回的就是rsa.PrivateKey
加密解密实现加密
func RsaEncrypt(origData []byte) ([]byte, error) { block, _ := pem.Decode(publicKey) if block == nil { return nil, errors.New("public key error") } pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } pub := pubInterface.(*rsa.PublicKey) return rsa.EncryptPKCS1v15(rand.Reader, pub, origData) }解密
func RsaDecrypt(ciphertext []byte) ([]byte, error) { block, _ := pem.Decode(privateKey) if block == nil { return nil, errors.New("private key error!") } priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return nil, err } return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext) }使用例子
package main import ( "fmt" ) func main() { data, err := RsaEncrypt([]byte("test")) if err != nil { panic(err) } origData, err := RsaDecrypt(data) if err != nil { panic(err) } fmt.Println(string(origData)) } // 此例子是加密完test后立马解密参考:
https://segmentfault.com/a/1190000024557845
https://www.jb51.net/article/89884.htm