Go加密算法总结 (4)

在加解密过程中,使用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呢?这又涉及到一堆概念。先不管这些,我也是看encodingcrypto这两个包的子包摸索出来的。

在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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyydpp.html