美文网首页
golang里面private key证书的加解密

golang里面private key证书的加解密

作者: CodingCode | 来源:发表于2020-03-06 05:29 被阅读0次

golang里面private key证书的加解密

private key证书的加解密是x509的内容,所以在golang的库里面就带有加解密的接口。
这里主要是使用golang x509包里面自带的加解密函数的用法举例。

  1. 加密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")
}
  1. 解密

解密输入一个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
}

相关文章

网友评论

      本文标题:golang里面private key证书的加解密

      本文链接:https://www.haomeiwen.com/subject/qfnprhtx.html