登录
首页 >  Golang >  Go问答

TLS连接中的身份验证和加密

来源:stackoverflow

时间:2024-03-07 09:51:25 179浏览 收藏

本篇文章向大家介绍《TLS连接中的身份验证和加密》,主要包括,具有一定的参考价值,需要的朋友可以参考一下。

问题内容

我正在与银行服务器集成,该服务器为我提供了证书。我根据证书创建了一个 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 错误:tls:错误的证书


解决方案


您似乎将证书颁发机构与客户端证书混淆了。客户端证书向服务器证明您的身份(就像用户名和密码一样),并且使用 ca 以便您知道您正在与正确的服务器通信。

从适合您的 openssl 命令来看,您的银行为您提供了客户端证书和密钥(尽管这非常不寻常;除了您自己之外,任何人都不应持有您的私钥,尤其是密码)。

The tls.Config.Certificates field(如果由客户端使用)用于配置客户端证书。

证书包含一个或多个证书链以呈现给连接的另一端。 [...] 进行客户端身份验证的客户端可以设置证书或 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},
    }
}

今天关于《TLS连接中的身份验证和加密》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>