golang里面private key证书的加解密
private key证书的加解密是x509的内容,所以在golang的库里面就带有加解密的接口。
这里主要是使用golang x509包里面自带的加解密函数的用法举例。
- 加密private key
加密输入一个pem,输出一个pem
// encrypt a pem private key
// input: pem raw
// output: pem raw
func EncryptPEM(pemRaw []byte, passwd []byte) ([]byte, error) {
block, _ := pem.Decode(pemRaw)
if block == nil {
return nil, fmt.Errorf("Failed decoding PEM. Block must be different from nil. [% x]", pemRaw)
}
der := block.Bytes
privateKey, err := DERToPrivateKey(der)
if err != nil {
return nil, err
}
block, err = EncryptPrivateKey(privateKey, passwd)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(block), nil
}
加密一个private key:
// encrypt a private key
// input: private key
// output: pem block
func EncryptPrivateKey(privateKey interface{}, passwd []byte) (*pem.Block, error) {
switch k := privateKey.(type) {
case *ecdsa.PrivateKey:
raw, err := x509.MarshalECPrivateKey(k)
if err != nil {
return nil, err
}
block, err := x509.EncryptPEMBlock(rand.Reader, "EC PRIVATE KEY", raw, passwd, x509.PEMCipherAES256)
if err != nil {
return nil, err
}
return block, nil
case *rsa.PrivateKey:
raw := x509.MarshalPKCS1PrivateKey(k)
block, err := x509.EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", raw, passwd, x509.PEMCipherAES256)
if err != nil {
return nil, err
}
return block, nil
default:
return nil, errors.New("Invalid key type. It must be *ecdsa.PrivateKey or *rsa.PrivateKey")
}
}
一个工具函数,把DER转化成一个private key:
func DERToPrivateKey(der []byte) (key interface{}, err error) {
if key, err = x509.ParsePKCS1PrivateKey(der); err == nil {
return key, nil
}
if key, err = x509.ParsePKCS8PrivateKey(der); err == nil {
switch key.(type) {
case *rsa.PrivateKey, *ecdsa.PrivateKey:
return
default:
return nil, errors.New("Found unknown private key type in PKCS#8 wrapping")
}
}
if key, err = x509.ParseECPrivateKey(der); err == nil {
return
}
return nil, errors.New("Invalid key type. The DER must contain an rsa.PrivateKey or ecdsa.PrivateKey")
}
- 解密
解密输入一个pem,输出一个pem
// decrypt a pem private key
// input: pem raw
// output: pem raw
func DecryptPEM(pemRaw []byte, passwd []byte) ([]byte, error) {
block, _ := pem.Decode(pemRaw)
if block == nil {
return nil, fmt.Errorf("Failed decoding PEM. Block must be different from nil. [% x]", pemRaw)
}
if ! x509.IsEncryptedPEMBlock(block) {
return nil, fmt.Errorf("Failed decryptPEM PEM. it's not a decryped PEM [%s]", pemRaw)
}
der, err := x509.DecryptPEMBlock(block, passwd)
if err != nil {
return nil, fmt.Errorf("Failed PEM decryption [%s]", err)
}
privateKey, err := DERToPrivateKey(der)
if err != nil {
return nil, err
}
var raw []byte
switch k := privateKey.(type) {
case *ecdsa.PrivateKey:
raw, err = x509.MarshalECPrivateKey(k)
if err != nil {
return nil, err
}
case *rsa.PrivateKey:
raw = x509.MarshalPKCS1PrivateKey(k)
default:
return nil, errors.New("Invalid key type. It must be *ecdsa.PrivateKey or *rsa.PrivateKey")
}
rawBase64 := base64.StdEncoding.EncodeToString(raw)
derBase64 := base64.StdEncoding.EncodeToString(der)
if rawBase64 != derBase64 {
return nil, errors.New("Invalid decrypt PEM: raw does not match with der")
}
block = &pem.Block{
Type: block.Type,
Bytes: der,
}
return pem.EncodeToMemory(block), nil
}
网友评论