【问题标题】:Get remote ssl certificate in golang在golang中获取远程ssl证书
【发布时间】:2015-07-31 17:19:59
【问题描述】:

我想通过 TLS 接收 TCP 连接。我想验证客户端证书并使用它向我的应用程序验证客户端。 Go 有标准的 crypto/tls 包。它可以验证客户端/服务器证书。但是我找不到获取远程(客户端)证书详细信息的方法,例如通用名称。

【问题讨论】:

  • 不会关闭——它的措辞很混乱,但“我如何检查 TLS 客户端证书的详细信息”是一个完全合理的问题。
  • 我对@9​​87654324@ 不是很熟悉,但看起来conn.ConnectionState().PeerCertificates[0] 给你一个x509.Certificateconn.VerifyHostname(name) 只会检查主机名。
  • 是的,谢谢。请改写为答案。

标签: ssl go


【解决方案1】:

必须致电crypto/tls/Conn.Handshake。 然后您可以阅读对等证书: tlsconn.ConnectionState().PeerCertificates[0].Subject.CommonName

【讨论】:

    【解决方案2】:

    以下代码可能会帮助您得到答案

    package main
    
    import (
        "crypto/tls"
        "fmt"
        "log"
    )
    
    func main() {
        conf := &tls.Config{
            InsecureSkipVerify: true,
        }
    
        conn, err := tls.Dial("tcp", "www.google.com:443", conf)
        if err != nil {
            log.Println("Error in Dial", err)
            return
        }
        defer conn.Close()
        certs := conn.ConnectionState().PeerCertificates
        for _, cert := range certs {
            fmt.Printf("Issuer Name: %s\n", cert.Issuer)
            fmt.Printf("Expiry: %s \n", cert.NotAfter.Format("2006-January-02"))
            fmt.Printf("Common Name: %s \n", cert.Issuer.CommonName)
    
        }
    }
    

    【讨论】:

    • 非常有帮助,谢谢
    【解决方案3】:

    使用 crypto/tls 时,您可以查询任何 Conn 对象的 ConnectionState:

    func (c *Conn) ConnectionState() ConnectionState
    

    ConnectionState 结构包含有关客户端证书的信息:

    type ConnectionState struct {
            PeerCertificates            []*x509.Certificate   // certificate chain presented by remote peer
    }
    

    x509.Certificate 应该很容易使用。

    在服务器请求客户端身份验证之前,您必须配置与服务器证书、客户端 CA(否则您将不得不手动验证信任链,您真的不希望那样)和 tls.RequireAndVerifyClientCert 的连接。例如:

    // Load my SSL key and certificate
    cert, err := tls.LoadX509KeyPair(settings.MyCertificateFile, settings.MyKeyFile)
    checkError(err, "LoadX509KeyPair")
    
    // Load the CA certificate for client certificate validation
    capool := x509.NewCertPool()
    cacert, err := ioutil.ReadFile(settings.CAKeyFile)
    checkError(err, "loadCACert")
    capool.AppendCertsFromPEM(cacert)
    
    // Prepare server configuration
    config := tls.Config{Certificates: []tls.Certificate{cert}, ClientCAs: capool, ClientAuth: tls.RequireAndVerifyClientCert}
    config.NextProtos = []string{"http/1.1"}
    config.Rand = rand.Reader
    

    【讨论】:

      【解决方案4】:

      有一种更简单的方法:

      func renewCert(w http.ResponseWriter, r *http.Request) {
      
        if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
          cn := strings.ToLower(r.TLS.PeerCertificates[0].Subject.CommonName)
          fmt.Println("CN: %s", cn)
        }
      
      }
      

      【讨论】:

      • 您的方法只能在 http gandler 中使用。我的问题是关于 tcp 连接的。
      猜你喜欢
      • 1970-01-01
      • 2013-02-22
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多