go 原生代碼搞定https雙向認證客戶端私鑰加密

最近有一個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請求的老套路了。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容