簡體   English   中英

具有證書,私鑰和通行短語的TLS

[英]TLS with Certificate, Private Key and Pass Phrase

我正在與向我提供證書的銀行服務器集成。 我使用證書創建了一個pem文件,因此現在我分別在pem文件中具有證書,私鑰和密鑰的通過短語。

如下所示,新生成的文件pem正在使用OpenSSL命令建立SSL連接:

openssl s_client -connect host:port -key key.pem -cert cert.pem

此命令要求輸入密碼,並且我可以連接。 但是我無法使用我的Go代碼連接到同一台計算機,該代碼如下所示:

package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "net/http"
)

func main() {
    caCert := []byte(`certs pem data`) // this contains both private key and certificates
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)

    // Setup HTTPS client
    tlsConfig := &tls.Config{
        RootCAs:            caCertPool,
        InsecureSkipVerify: true,
    }
    tlsConfig.BuildNameToCertificate()
    transport := &http.Transport{TLSClientConfig: tlsConfig}
    client := &http.Client{Transport: transport}

    httpRequest, _ := http.NewRequest("GET", "https://test.com", nil)
    resp, err := client.Do(httpRequest)
    fmt.Printf("resp: [%v] \n Error: [%v]", resp, err)
}

我也不確定在我的HTTP請求中的何處添加密碼。

我得到的錯誤: remote error: tls: bad certificate

您似乎將證書頒發機構與客戶端證書混淆了。 客戶端證書向服務器證明您的身份(就像用戶名和密碼一樣),並且使用CA,以便您知道自己正在與正確的服務器通信。

從對您有用的openssl命令來看,您的銀行為您提供了客戶證書和密鑰(盡管這非常不實用;除了您自己之外,沒有人應該持有您的私鑰,尤其是密碼短語)。

tls.Config.Certificates字段 (如果由客戶端使用)用於配置客戶端證書。

證書包含一個或多個證書鏈,以呈現給連接的另一端。 [...]執行客戶端身份驗證的客戶端可以設置證書或GetClientCertificate。

TLS證書通常與tls.LoadX509KeyPairtls.X509KeyPair一起加載。 但是,這些功能不直接支持加密密鑰。

相反,您必須自己加載密鑰,使用x509.DecryptPEMBlock對其進行解密,然后才能使用tls.X509KeyPair。

以下示例使用EC密鑰,因為它的編碼很短,但是與RSA密鑰相同。

package main

import (
    "crypto/tls"
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "log"
    "net/http"
)

var bundle = []byte(`
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,99586A658F5D2DAC4A8A3CA387CF71CE

25EtKb7ycOI/5R47fYwpiaNERgYnCxCtcrMXJuOgueuxUXjiU0n93hpUpIQqaTLH
dDKhsR1UHvGJVTV4h577RQ+nEJ5z8K5Y9NWFqzfa/Q5SY43kqqoJ/fS/OCnTmH48
z4bL/dJBDE/a5HwJINgqQhGi9iUkCWUiPQxriJQ0i2s=
-----END EC PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIB2TCCAX+gAwIBAgIUUTZvgwwnbC05WHgIHMXxrbZzr6wwCgYIKoZIzj0EAwIw
QjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwT
RGVmYXVsdCBDb21wYW55IEx0ZDAeFw0xOTA1MTQxMzAwMDJaFw0xOTA1MTUxMzAw
MDJaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNV
BAoME0RlZmF1bHQgQ29tcGFueSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AAScgLGx6SXchEo/s0X3AoF0mQkh3bGf9QY0s/2dPqf3/9irwz35DiDGoaP+FDZv
HnUX+D3tUEPhxkLyzWKKT9HHo1MwUTAdBgNVHQ4EFgQU3eB8oRcmvzZrx9Dkb6ma
MMtu1MkwHwYDVR0jBBgwFoAU3eB8oRcmvzZrx9Dkb6maMMtu1MkwDwYDVR0TAQH/
BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiAvw/FqAmGbSlBklp6AHJy9kf9VPyhe
RA93ccNQ+7m1fAIhAOXr8c2QsH2oOYRTbn6bPZjkYQ2jLMaxatKhChBIuyZA
-----END CERTIFICATE-----
`)

func main() {
    keyBlock, certsPEM := pem.Decode(bundle)

    fmt.Println(x509.IsEncryptedPEMBlock(keyBlock)) // Output: true

    // Decrypt key
    keyDER, err := x509.DecryptPEMBlock(keyBlock, []byte("foobar"))
    if err != nil {
        log.Fatal(err)
    }

    // Update keyBlock with the plaintext bytes and clear the now obsolete
    // headers.
    keyBlock.Bytes = keyDER
    keyBlock.Headers = nil

    // Turn the key back into PEM format so we can leverage tls.X509KeyPair,
    // which will deal with the intricacies of error handling, different key
    // types, certificate chains, etc.
    keyPEM := pem.EncodeToMemory(keyBlock)

    cert, err := tls.X509KeyPair(certsPEM, keyPEM)
    if err != nil {
        log.Fatal(err)
    }

    config := &tls.Config{
        Certificates: []tls.Certificate{cert},
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM