Go语言 为什么连接到本地主机TLS服务器失败?

z3yyvxxp  于 2023-10-14  发布在  Go
关注(0)|答案(1)|浏览(136)

我有一个本地生成的X.509证书(即CA证书)和私钥。“CA”证书用于签署客户端证书。它还用作在本地主机上运行的HTTP+TLS Web服务器的服务器证书。
客户端获取由CA证书签名的证书,并尝试通过提供新证书连接到HTTP+TLS Web服务器。Go客户端设置了一个只包含CA证书的根信任池。服务器也将其客户端信任根设置为Go中的CA证书。
CA证书:

-----BEGIN CERTIFICATE-----
MIICEDCCAbegAwIBAgIUT2sxtpA9k1VVdb/DSVIE3oYANf8wCgYIKoZIzj0EAwIw
XjEtMCsGA1UEAwwkNmI5MGNhYmMtZTZhYS01NjBhLWI1YzMtODFmZWViMTRkZTUw
MS0wKwYDVQQKDCQ5MWJjMGFlOC0xMzA3LTRmMTMtODBlNC1jZWY0NjgxNjAxNDIw
HhcNMjMwOTI4MDYyNjI4WhcNMzMwOTI1MDYyNjI4WjBeMS0wKwYDVQQDDCQ2Yjkw
Y2FiYy1lNmFhLTU2MGEtYjVjMy04MWZlZWIxNGRlNTAxLTArBgNVBAoMJDkxYmMw
YWU4LTEzMDctNGYxMy04MGU0LWNlZjQ2ODE2MDE0MjBZMBMGByqGSM49AgEGCCqG
SM49AwEHA0IABBN2QUl7jzfxkhX/hOZ+uFbb+TcfqdTzgIQRZrFjaySQvQ2je8Mb
MOEB1xjISXd7m4O+fOjHvdKgP+XQjOwctbejUzBRMB0GA1UdDgQWBBTKL5QNQ/tt
AGYJUEyMH6O8we+Y9DAfBgNVHSMEGDAWgBTKL5QNQ/ttAGYJUEyMH6O8we+Y9DAP
BgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIHAT9FTUGnOeYUv8kbRO
OyMIiaWoIMR7G94YLVhGvyIyAiAe2q/SvkNhA6PaUGFQXL4CDFCDW4OXCPbtJ1AU
RPTZ1Q==
-----END CERTIFICATE-----

服务器是用Go1.21编写的。它被设置为信任由CA证书签名的客户端证书。我尝试了Go客户端和curl。Go客户端设置了一个仅由CA证书组成的证书信任池。curl客户端没有设置这个信任池,但是我已经关闭了-k的验证。
TLS Web服务器是这样设置的:

// cert is a tls.Certificate containing the CA certificate
// clientCertPool is a certificate pool containing the CA certificate too
server := http.Server{
        Handler: hdlr,
        Addr:    addr,
        TLSConfig: &tls.Config{
            Certificates: []tls.Certificate{cert},
            ClientAuth:   tls.RequireAndVerifyClientCert,
            ClientCAs:    clientCertPool,
            KeyLogWriter: ssllog,
        },
    }

这是客户端:

func HTTPClient(clientCert tls.Certificate, roots *x509.CertPool, ssllog io.Writer) *http.Client {
    tlsConfig := &tls.Config{
        Certificates: []tls.Certificate{clientCert},
        RootCAs:      roots,
        KeyLogWriter: ssllog,
    }
    tlsTransport := http.DefaultTransport.(*http.Transport).Clone()
    tlsTransport.TLSClientConfig = tlsConfig

    return &http.Client{
        Transport: tlsTransport,
    }
}

错误

当Go客户端连接到TLS服务器时,我看到以下错误:
Go客户端:Get \"https://localhost:8443/v1/description\": remote error: tls: internal error
TLS服务器:http: TLS handshake error from 127.0.0.1:55740: invalid argument
当curl连接到TLS服务器时,我看到的是这个。
curl :curl: (35) LibreSSL/3.3.6: error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error
TLS服务器:http: TLS handshake error from 127.0.0.1:55792: invalid argument
服务器报告的错误在两次都是相同的。令我困惑的是,这个设置在一个月前还有效。只有CA证书可能略有变化,但其他一切都是一样的。
如果有必要,我可以分享更多的代码。如果有帮助的话我还能捕捉到线痕。
CA server和TLS Web服务器的代码是开源的,可在https://github.com/RealImage/bifrost上获得。

qhhrdooz

qhhrdooz1#

您的证书缺少RFC 5280中用作TLS服务器证书所需的几乎所有扩展。
举例来说:
4.2.1.3.密钥使用
密钥使用扩展定义了证书中包含的密钥的用途(例如,加密、签名、证书签名)。当要限制可用于多于一个操作的密钥时,可以采用使用限制。例如,当RSA密钥仅用于验证公钥证书和CRL以外的对象上的签名时,将AssertdigitalSignature和/或nonRepudiation位。同样,当RSA密钥仅用于密钥管理时,keyEncipherment位将被Assert。
一致性CA必须在包含公钥的证书中包含此扩展,这些公钥用于验证其他公钥证书或CRL上的数字签名
注意“必须”的使用。您的证书还缺少许多其他扩展。
这是您的证书的文本说明:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            4f:6b:31:b6:90:3d:93:55:55:75:bf:c3:49:52:04:de:86:00:35:ff
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN = 6b90cabc-e6aa-560a-b5c3-81feeb14de50, O = 91bc0ae8-1307-4f13-80e4-cef468160142
        Validity
            Not Before: Sep 28 06:26:28 2023 GMT
            Not After : Sep 25 06:26:28 2033 GMT
        Subject: CN = 6b90cabc-e6aa-560a-b5c3-81feeb14de50, O = 91bc0ae8-1307-4f13-80e4-cef468160142
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:13:76:41:49:7b:8f:37:f1:92:15:ff:84:e6:7e:
                    b8:56:db:f9:37:1f:a9:d4:f3:80:84:11:66:b1:63:
                    6b:24:90:bd:0d:a3:7b:c3:1b:30:e1:01:d7:18:c8:
                    49:77:7b:9b:83:be:7c:e8:c7:bd:d2:a0:3f:e5:d0:
                    8c:ec:1c:b5:b7
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                CA:2F:94:0D:43:FB:6D:00:66:09:50:4C:8C:1F:A3:BC:C1:EF:98:F4
            X509v3 Authority Key Identifier: 
                keyid:CA:2F:94:0D:43:FB:6D:00:66:09:50:4C:8C:1F:A3:BC:C1:EF:98:F4
            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:70:13:f4:54:d4:1a:73:9e:61:4b:fc:91:b4:4e:
         3b:23:08:89:a5:a8:20:c4:7b:1b:de:18:2d:58:46:bf:22:32:
         02:20:1e:da:af:d2:be:43:61:03:a3:da:50:61:50:5c:be:02:
         0c:50:83:5b:83:97:08:f6:ed:27:50:14:44:f4:d9:d5

这将以多种方式作为TLS服务器证书验证失败:
1.没有Subject Alternative Names标识它所用于的TLS服务器。
1.该证书没有用于TLS服务器密钥使用的其他Basic Constraints(如keyEncipherment),也没有用作CA证书的其他CASigning
1.证书缺少直接将其标识为TLS服务器证书= serverAuth的扩展密钥使用属性。
我怀疑您的客户端证书还缺少用作客户端证书所必需的X509扩展。
你知道你以前的CA证书签署的旧客户端证书对新的CA证书是无用的吗?它们可以工作的唯一方法是,如果您将旧证书添加到服务器的受信任CA证书集,并且假设您的旧证书没有过期。
参见OpenSSL's x509v3_config man page

x509v3_config
姓名

x509v3_config - X509 V3证书扩展配置格式描述
一些OpenSSL实用程序可以根据配置文件的内容向证书或证书请求添加扩展。
...

相关问题