美文网首页数据分析师的日常
go 原生代码搞定https双向认证客户端私钥加密

go 原生代码搞定https双向认证客户端私钥加密

作者: 采菊东篱下 | 来源:发表于2019-01-15 14:15 被阅读10次

    最近有一个https双向认证的项目,客户端的证书是加密的,之前用python requests 做原型测试发现不支持加密,需要运行的时候在终端输入密码。

    当然一开始在网上搜索go也没有发现比较好的方案,基本都是通过openssl工具先在命令行把加密的key转换成非加密的,然后调用tls.LoadX509KeyPair()函数。

    但是对于加密的的客户端证书,tls.LoadX509KeyPair()函数并没有提供一个密码参数来自动解密,所以没办法,只能自己摸索喽。

    使用Go自然是相信go本身的强大,各种搜索然后结合相关的API文档后摸索出了直接通过go原生代码来解密的流程,不依赖任何第三发库和命令工具。

    import (
        "crypto/tls"
        "crypto/x509"
        "encoding/pem"
        "io/ioutil"
        "net/http"
    )
    
    func InitHttpsClient(keyPem, certPem, pemPass string) *http.Client {
        // 读取私钥文件
        keyBytes, err := ioutil.ReadFile(keyPem)
        if err != nil {
            panic("Unable to read keyPem")
        }
        // 把字节流转成PEM结构
        block, rest := pem.Decode(keyBytes)
        if len(rest) > 0 {
            panic("Unable to decode keyBytes")
        }
        // 解密PEM
        der, err := x509.DecryptPEMBlock(block, []byte(pemPass))
        if err != nil {
            panic("Unable to decrypt pem block")
        }
        // 解析出其中的RSA 私钥
        key, err := x509.ParsePKCS1PrivateKey(der)
        if err != nil {
            panic("Unable to parse pem block")
        }
        // 编码成新的PEM 结构
        keyPEMBlock := pem.EncodeToMemory(
            &pem.Block{
                Type:  "RSA PRIVATE KEY",
                Bytes: x509.MarshalPKCS1PrivateKey(key),
            },
        )
        // 读取证书文件
        certPEMBlock, err := ioutil.ReadFile(certPem)
        if err != nil {
            panic("Unable to read certPem")
        }
        // 生成密钥对
        cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
        if err != nil {
            panic("Unable to read privateKey")
        }
    
        client := &http.Client{
            Transport: &http.Transport{
                TLSClientConfig: &tls.Config{
                    Certificates:       []tls.Certificate{cert},
                    InsecureSkipVerify: true,
                },
            },
        }
        return client
    }
    
    

    剩下的就是http请求的老套路了。

    相关文章

      网友评论

        本文标题:go 原生代码搞定https双向认证客户端私钥加密

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