如何在Go中验证已签名的证书时间戳(SCT)



我正在编写一个Go HTTP客户端应用程序,它需要验证SCT才能利用证书透明度。这在最新的Go版本中自动支持吗?你是如何做到这一点的?

这里有两个方面:

  1. 从TLS连接检索SCT
  2. 根据CT日志验证SCT

检索SCT在标准库中很容易完成,每个RFC 6962:有三种不同的情况

  • 作为叶证书本身的扩展
  • 作为握手中的TLS扩展
  • OCSP响应中

所有这些都可以通过tl获得。各自字段中的ConnectionState:

  • state.PeerCertificates[0].Extensions,在ID为asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2}的扩展下
  • state.SignedCertificateTimestamps
  • state.OCSPResponse

这些仍然需要正确解析。

验证SCT比较棘手,而且不是标准库的部分。这涉及以下内容:

  • 具有可信CT日志列表
  • 查找其公钥用于对SCT进行签名的CT日志
  • 验证签名
  • 验证证书是否包含在CT的merkle树中并检查时间戳

这可以使用证书透明go实用程序拼凑而成,但它们还没有包括将其用作库的快速简便的方法。

github.com/mberhault/go-sct上有一个库试图让这一切变得更容易

免责声明:我是github.com/mberhault/go-sct的作者。

import "github.com/mberhault/go-sct"
// Verifying the SCTs after a HTTPS GET request.
resp, err := http.Get("https://www.certificate-transparency.org")
if err != nil {
panic("get failed " + err.Error())
}
err = sct.CheckConnectionState(resp.TLS)
if err != nil {
panic("SCT check failed " + err.Error())
}

tls也可以这样做。通过其他方法(在tls.Conn上或在tls.Config.VerifyConnection回调中(获得的ConnectionState。

最新更新