在golang中获取远程ssl证书

时间:2015-07-31 17:19:59

标签: ssl go

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

4 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

有一种更简单的方法:

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

}

答案 3 :(得分:1)

以下代码可以帮助您获得答案

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)

    }
}