encoding/pem
2018-12-25 本文已影响3人
酷走天涯
pem包实现了PEM数据编码(源自保密增强邮件协议)。目前PEM编码主要用于TLS密钥和证书
PEM 编码格式如下
-----BEGIN Type-----
Headers
base64-encoded Bytes
-----END Type-----
编码
func Encode(out io.Writer, b *Block) error
type Block struct {
Type string // 得自前言的类型(如"RSA PRIVATE KEY")
Headers map[string]string // 可选的头项
Bytes []byte // 内容解码后的数据,一般是DER编码的ASN.1结构
}
下面我们就以ras加密方式为例,看一个pem编码的实现过程
package main
import (
"crypto/rsa"
"crypto/rand"
"fmt"
"encoding/pem"
"crypto/x509"
"os"
"log"
"io/ioutil"
"errors"
)
var privite_key_path = "/Users/xujie/go/src/awesomeProject/main/private.pem"
var public_key_path = "/Users/xujie/go/src/awesomeProject/main/public.pem"
func main() {
// 生成公钥和私钥
generatePublick(generatePrivate())
src := []byte(`{"name":"酷走天涯"}`)
// 公钥加密
cryptoData,error := rsaEncrypt(src)
if error != nil {
log.Fatal(error)
}
fmt.Println("加密:",cryptoData)
// 私钥解密
dst,error := rsaDecrypt(cryptoData)
if error != nil {
log.Fatal(error)
}
fmt.Println("解密:",string(dst))
}
// 生成私钥
func generatePrivate() *rsa.PrivateKey{
privateKey,error := rsa.GenerateKey(rand.Reader,2048)
if error != nil {
fmt.Println(error)
}
derStream := x509.MarshalPKCS1PrivateKey(privateKey)
block := &pem.Block{Type:"RSA PRIVATE KEY",Bytes:derStream}
file,error := os.Create(privite_key_path)
if error != nil {
fmt.Println(error)
}
error = pem.Encode(file,block)
if error != nil {
fmt.Println(error)
}
return privateKey
}
// 生成公钥
func generatePublick(privateKey *rsa.PrivateKey){
publicKey := privateKey.Public()
derStream,error := x509.MarshalPKIXPublicKey(publicKey)
if error != nil{
fmt.Println(error)
}
block := &pem.Block{Type:"RSA PUBLIC KEY",Bytes:derStream}
file,error := os.Create(public_key_path)
if error != nil {
fmt.Println(error)
}
error = pem.Encode(file,block)
if error != nil {
fmt.Println(error)
}
}
// 公钥加密
func rsaEncrypt(origData []byte) ([]byte, error) {
// 从文件中读取公钥编码字节流
file,error := os.Open(public_key_path)
if error != nil{
log.Fatal(error)
}
publicKey,error := ioutil.ReadAll(file)
if error != nil{
log.Fatal(error)
}
// 解码对应的block块数据
block, _ := pem.Decode(publicKey)
if block == nil {
return nil, errors.New("public key error")
}
// 获取公钥key值
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) {
// 从文件中读取私钥pem字节流
file,error := os.Open(privite_key_path)
if error != nil{
log.Fatal(error)
}
privateKey,error := ioutil.ReadAll(file)
if error != nil{
log.Fatal(error)
}
// 解码出对应的block值
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)
}
image.png
rsa.GenerateKey(rand.Reader,2048)
2048 是默认的的数据长度,也可以设置其他值