简体   繁体   English

在 golang 中获取远程 ssl 证书

[英]Get remote ssl certificate in golang

I want to receive a TCP connection over TLS.我想通过 TLS 接收 TCP 连接。 I want to validate client certificate and use it to authenticate the client to my application.我想验证客户端证书并使用它来验证客户端到我的应用程序。 Go has the standard crypto/tls package. Go 有标准的crypto/tls包。 It can validate client/server certificates.它可以验证客户端/服务器证书。 But I can't find way to get details of the remote (client) certificate, like the common name.但是我找不到获取远程(客户端)证书详细信息的方法,例如通用名称。

Have to call crypto/tls/Conn.Handshake .必须调用crypto/tls/Conn.Handshake Then you can read peer certificate: tlsconn.ConnectionState().PeerCertificates[0].Subject.CommonName然后你可以读取对等证书:tlsconn.ConnectionState().PeerCertificates[0].Subject.CommonName

Following code may help you get your answer以下代码可能会帮助您获得答案

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)

    }
}

When working with crypto/tls you can query any Conn object for ConnectionState:使用crypto/tls 时,您可以查询 ConnectionState 的任何 Conn 对象:

func (c *Conn) ConnectionState() ConnectionState

The ConnectionState struct contains information about the client certificate: ConnectionState 结构包含有关客户端证书的信息:

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

The x509.Certificate should be pretty straightforward to work with. x509.Certificate应该很容易使用。

Before the server requests for client authentication, you have to configure the connection with the server certificate, client CA (otherwise you will have to verify the trust chain manually, you really don't want that), and tls.RequireAndVerifyClientCert.在服务器请求客户端身份验证之前,您必须使用服务器证书、客户端 CA(否则您必须手动验证信任链,您真的不想要)和 tls.RequireAndVerifyClientCert 配置连接。 For example:例如:

// 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

There is an easier way to do that:有一种更简单的方法可以做到这一点:

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)
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM