为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Go 中创建使用 TLS 客户端身份验证的测试服务器?

如何在 Go 中创建使用 TLS 客户端身份验证的测试服务器?

Go
繁华开满天机 2022-05-23 17:46:40
我想为从设备证书中提取某些信息的 HTTP 处理程序编写一个单元测试。我找到了这个要点https://gist.github.com/ncw/9253562,它用于openssl生成证书并简单地读取其client.go和server.go. 然而,为了让事情更加透明,我想使用 Go 的标准库生成证书。但是,当我运行它时,我收到以下错误:> go test ./...2020/04/06 15:12:30 http: TLS handshake error from 127.0.0.1:58685: remote error: tls: bad certificate--- FAIL: TestDeviceFromTLS (0.05s)    main_test.go:64:             Error Trace:    main_test.go:64            Error:          Received unexpected error:                            Put https://127.0.0.1:58684: x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs            Test:           TestDeviceFromTLSFAILFAIL    github.com/kurtpeek/client-auth-test    0.379s我不确定如何处理错误消息无法验证 127.0.0.1 的证书,因为它不包含任何 IP SAN因为我在IPAddresses创建证书时正在现场传递。关于这里有什么问题的任何想法?
查看完整描述

3 回答

?
MYYA

TA贡献1868条经验 获得超4个赞

我不确定如何处理错误消息


无法验证 127.0.0.1 的证书,因为它不包含任何 IP SAN


因为我在创建证书时传入了 IPAddresses 字段。关于这里有什么问题的任何想法?


问题是您在创建客户端IPAddresses证书时传递了该字段,而不是在创建服务器证书时传递,因为您的服务器只是将 CA 证书用作自己的证书,而 CA 证书(正确) 不包括 IP 地址,因此错误消息是正确的:


caKey, caKeyPEM := generateKey(t)

caCert, caCertPEM := generateRootCert(t, caKey)


serverCert, err := tls.X509KeyPair(caCertPEM, caKeyPEM)

您应该以与创建客户端证书相同的方式创建由 CA(或 CA)签名的服务器证书,并将其用于测试服务器。


通常,以您正在做的方式让单个密钥作为 CA 和作为 TLS 服务器执行双重职责是自找麻烦,在这里没有充分的理由这样做;虽然 RFC5280 实际上并没有禁止这种做法,但它至少似乎不鼓励这种做法,除非有特殊情况需要。


但是,就目前而言,您使用 CA 证书的方式在技术上不符合 RFC5280,因为它包含一个扩展的密钥使用扩展,仅指定 TLS 客户端和服务器身份验证,但您使用它来签署证书。它可能是宽容的,但在没有anyExtendedKeyUsage关键目的的情况下x509.CreateCertificate,这里真的应该失败。


查看完整回答
反对 回复 2022-05-23
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

该错误与 X509 证书中存在的 SAN 字段扩展有关。X509 证书中的 SAN 字段可以包含以下类型的条目;

  1. DNS 名称

  2. IP地址

  3. URI

详细信息可以在这里找到

通常在证书验证过程中,可以在某些系统上执行 SAN 扩展验证。因此,您会看到这样的错误消息

您有两个选项可以避免此错误消息,

  1. 在证书中添加 SAN IP 字段

  2. 跳过证书验证步骤 [这是您通过注释掉所做的]


查看完整回答
反对 回复 2022-05-23
?
炎炎设计

TA贡献1808条经验 获得超4个赞

仔细观察ncw's gist,我注意到一个关键的区别是InsecureSkipVerify客户端的 TLS 配置中的选项设置为true. 我添加了这个,所以


    client.Transport.(*http.Transport).TLSClientConfig = &tls.Config{

        Certificates:       []tls.Certificate{deviceCert},

        RootCAs:            pool,

        InsecureSkipVerify: true,

    }

现在测试通过了。


服务器证书的验证超出了这个测试的范围,所以这对我的目的来说已经足够了,但我仍然很想知道验证失败的原因。


查看完整回答
反对 回复 2022-05-23
  • 3 回答
  • 0 关注
  • 203 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信