golang-标准库(crypto/rsa)

本文讲解使用go提供的rsa包生成私匙和公匙,以及使用它们进行加解密

公匙是根据私匙计算而来的,go中公匙同样也是通过私匙获得,下面看获取私匙和公匙的方法:

// 下面是一个生成私匙和公匙的方法
// privateKey, publicKey分别是私匙和公匙的文件可写流,私匙和公匙分别写入到这二个文件中
// bits为生成私匙的长度
func generatPrivateAndPublicKey(privateKey, publicKey io.Writer, bits int) error {

	// 生成私匙,提供一个随机数和私匙的长度,目前主流的长度为1024、2048、3072、4096,
    // 但1024已经不在推荐使用了。
	priKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return err
	}
    // 将rsa私钥序列化为ASN.1 PKCS#1 DER编码
	data := x509.MarshalPKCS1PrivateKey(priKey)

	block := pem.Block{
		Type:"RSA PRIVATE KEY",
		Bytes:data,
	}
    // 将私匙做pem数据编码,然后写入文件
	err = pem.Encode(privateKey, &block)
	if err != nil {
		return err
	}

	// 生成公匙
	pubKey := priKey.PublicKey
    // 将rsa公钥序列化为ASN.1 PKCS#1 DER编码
	pubKeyData := x509.MarshalPKCS1PublicKey(&pubKey)
    // 将公匙做pem数据编码,然后写入文件
	err = pem.Encode(publicKey, &pem.Block{
		Type: "RSA PUBLIC KEY",
		Bytes: pubKeyData,
	})
	if err != nil {
		return err
	}

	return nil

}

下面看使用公匙加密和使用私匙解密的方法:

1.由于私匙和公匙都是存放在文件中的,需要先把私匙和公匙解析为go中对应的私匙公匙结构体对象,下面看方法:


// 解析公匙
func parsingRsaPublicKey(file string) (*rsa.PublicKey, error) {
	// 读取公匙文件
	pubByte,err := ioutil.ReadFile(file)
	if err != nil {
		return nil,err
	}
	// pem解码
	b,_ := pem.Decode(pubByte)
	if b == nil {
		return nil,errors.New("error public key")
	}
	// der解码,最终返回一个公匙对象
	pubKey,err := x509.ParsePKCS1PublicKey(b.Bytes)
	if err != nil {
		return nil,err
	}
	return pubKey,nil
}

// 解析私匙
func parsingRsaPrivateKey(file string) (*rsa.PrivateKey, error) {
	// 读取私匙
	priByte,err := ioutil.ReadFile(file)
	if err != nil {
		return nil,err
	}
	// pem解码
	b,_ := pem.Decode(priByte)
	if b == nil {
		return nil,errors.New("error private key")
	}
	// der加密,返回一个私匙对象
	prikey,err := x509.ParsePKCS1PrivateKey(b.Bytes)
	if err != nil {
		return nil,err
	}
	return prikey,nil
}

2.使用私匙和公匙加解密方法:


//  rsa公匙加密
func rsaPublicKeyEncrypt(src []byte, publickey *rsa.PublicKey) ([]byte, error) {
	// 使用公匙加密数据,需要一个随机数生成器和公匙和需要加密的数据
	data,err := rsa.EncryptPKCS1v15(rand.Reader, publickey,src)
	if err != nil {
		return nil,err
	}
	return data,nil
}
// rsa私匙解密
func rsaPrivateKeyDecrypt(src []byte, privateKey *rsa.PrivateKey) ([]byte, error) {
	// 使用私匙解密数据,需要一个随机数生成器和私匙和需要解密的数据
	data,err := rsa.DecryptPKCS1v15(rand.Reader, privateKey,src)
	if err != nil {
		return nil,err
	}
	return data,nil
}

3.下面看测试代码:


func main() {

	// 生成私匙和公匙
	pri,_ := os.Create("pri.key")
	pub,_ := os.Create("pub.key")
	defer pri.Close()
	defer pub.Close()
	generatPrivateKey(pri,pub,2048)


	pubKey,_ := parsingRsaPublicKey("pub.key") // 解密公匙
	encryData,_ := rsaPublicKeyEncrypt([]byte("hello world"),pubKey) // 加密数据
	fmt.Printf("%x\n",encryData)

	priKey,_ := parsingRsaPrivateKey("pri.key") // 解密私匙
	decryData,_ := rsaPrivateKeyDecrypt(encryData,priKey) // 解密数据
	fmt.Printf("%s\n",decryData)

}

不过,go只提供了公匙加密和私匙解密的方法,并没有直接提供公匙加密私匙解密的方法。

你可能感兴趣的:(go,golang标准库)