美文网首页
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