首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在http.NewRequest中检查服务器SSL/TLS证书的指纹

在http.NewRequest中检查服务器SSL/TLS证书的指纹
EN

Stack Overflow用户
提问于 2014-11-19 08:19:33
回答 2查看 5.2K关注 0票数 5

在golang中,如何在http请求期间检查服务器SSL/TLS证书的指纹?

这个ruby code显示了我想在Go中做什么:

代码语言:javascript
复制
  @verify_callback = proc do |preverify_ok, store_context|
    if preverify_ok and store_context.error == 0
      certificate = OpenSSL::X509::Certificate.new(store_context.chain[0])
      fingerprint = Digest::SHA1.hexdigest(certificate.to_der).upcase.scan(/../).join(":")
      $valid_fingerprints.include?(fingerprint)
    else
      false
    end
  end
EN

回答 2

Stack Overflow用户

发布于 2016-06-28 09:49:06

一般来说,在Go中生成证书指纹的过程非常简单。如果您已经有一个存储在cert中的x509.Certificate结构,那么您需要做的就是

代码语言:javascript
复制
sha1Fingerprint := sha1.Sum(cert.Raw)

在请求完成后从HTTP response struct获取证书也非常简单(使用resp.TLS.PeerCertificates),但这似乎不是您所需要的。

如果您需要在TLS连接建立时访问服务器的证书,我认为您需要创建自己的http.Transport,并将DialTLS的自定义实现交给它。然后,在配置http.Client发出出站请求时使用该传输。

在您的自定义DialTLS函数中,您可以访问连接状态信息,如服务器的证书链,并且可以从那里执行SHA1指纹生成。

票数 5
EN

Stack Overflow用户

发布于 2014-11-29 01:49:26

您可能不应该自己实现证书检查,而是让net/http根据您提供的有效CA进行检查。而且,通常直接使用指纹也不值得这么麻烦。

例如,这就是如何设置要求客户端使用证书进行身份验证的HTTPS服务器。客户端证书必须由CA签名,否则SSL/TLS握手将停止。

代码语言:javascript
复制
    // Server's own certificate & key
    cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
    if err != nil {
       panic(err)
    }

    // Load the CA certificate(s)
    capool := x509.NewCertPool()
    cacert, err := ioutil.ReadFile("ca.crt")
    if err != nil {
       panic(err)
    }
    capool.AppendCertsFromPEM(cacert)

    // Server configuration
    config := tls.Config{Certificates: []tls.Certificate{cert}, ClientCAs: capool, ClientAuth: tls.RequireAndVerifyClientCert}
    config.NextProtos = []string{"http/1.1"}
    config.Rand = rand.Reader // Strictly not necessary, should be default

    // TLS web server
    myTLSWebServer := &http.Server{Addr: "myaddress", TLSConfig: &config, Handler: nil}

    // .. proceed with setting handlers etc
    http.HandleFunc("/", myHandler)

    // Bind to port and start the server up
    conn, err := net.Listen("tcp", settings.ServiceAddress)
    if err != nil {
       panic(err)
    }
    tlsListener := tls.NewListener(conn, &config)
    myTLSWebServer.Serve(tlsListener)

阅读tls.Config的文档将向您展示,通过更改参数(ClientAuth、ClientCA、证书、RootCA),您可以轻松地选择不同的模式来检查证书。你通常会得到错误返回的失败。

如果您确实坚持检查指纹,您可以从Request TLS *tls.ConnectionState获取TLS状态。我认为您可能应该使用该结构中的签名来进行指纹识别。在我的脑海中,大概有这样的东西

代码语言:javascript
复制
func lol(r *http.Request) {
    tls := r.TLS
    if tls != nil {
       // Try the first one for simplicity
       cert := tls.PeerCertificates[0]
       signature := cert.Signature
       // Do something with the signature
    }
}

应该能行得通。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27006725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档