我正在尝试使用自签名服务器证书建立TLS连接。
我使用以下示例代码生成证书:http://golang.org/src/pkg/crypto/tls/generate_cert.go
我的相关客户端代码如下:
// server cert is self signed -> server_cert == ca_cert
CA_Pool := x509.NewCertPool()
severCert, err := ioutil.ReadFile("./cert.pem")
if err != nil {
log.Fatal("Could not load server certificate!")
}
CA_Pool.AppendCertsFromPEM(severCert)
config := tls.Config{RootCAs: CA_Pool}
conn, err := tls.Dial("tcp", "127.0.0.1:8000", &config)
if err != nil {
log.Fatalf("client: dial: %s", err)
}
相关的服务器代码如下:
cert, err := tls.LoadX509KeyPair("./cert.pem", "./key.pem")
config := tls.Config{Certificates: []tls.Certificate{cert}}
listener, err := tls.Listen("tcp", "127.0.0.1:8000", &config)
for {
conn, err := listener.Accept()
if err != nil {
log.Printf("server: accept: %s", err)
break
}
log.Printf("server: accepted from %s", conn.RemoteAddr())
go handleConnection(conn)
}
因为服务器证书是自签名的,所以使用与服务器和客户端CA_Pool相同的证书,但这似乎不起作用,因为我总是收到此错误:
client: dial: x509: certificate signed by unknown authority
(possibly because of "x509: invalid signature: parent certificate
cannot sign this kind of certificate" while trying to verify
candidate authority certificate "serial:0")
我的错误是什么?
答案 0 :(得分:25)
它最终适用于x509.CreateCertificate中构建的go, 问题是我没有设置IsCA:true flag , 我只设置了x509.KeyUsageCertSign ,这使得创建自签名证书有效,但在验证证书链时崩溃了。
答案 1 :(得分:10)
问题是您需要在服务器端配置中使用CA证书,并且此CA必须已签署服务器证书。
我已经编写了一些将generate作为CA证书的Go代码,但它尚未经过任何人的审核,而且主要是用于玩客户端证书的玩具。最安全的赌注可能是使用openssl ca
生成并签署证书。基本步骤将是:
tls.Config
RootCAs
tls.Config
。答案 2 :(得分:4)
https://github.com/deckarep/EasyCert/releases(仅支持OSX,因为它在内部使用openssl工具)
和来源:
https://github.com/deckarep/EasyCert
基本上使用这个工具,它会生成一个文件包,但是你需要它完成时输出的三个文件。
答案 3 :(得分:0)
我在golang中使用mysql客户端时看到了相同的错误:
True
并将Failed to connect to database: x509: cannot validate certificate for 10.111.202.229 because it doesn't contain any IP SANs
设置为InsecureSkipVerify
(以跳过证书验证)为我解决了这个问题:
https://godoc.org/crypto/tls#Config
以下代码对我有用:
true
答案 4 :(得分:0)
就我而言,我附加的证书未正确编码为pem格式。 如果使用keytools,请确保在从密钥库中导出证书时附加-rfc,可以在文本编辑器中打开编码的pem以显示:
-----BEGIN CERTIFICATE-----
MIIDiDCCAnCgAwIBAgIEHKSkvDANBgkqhkiG9w0BAQsFADBi...
答案 5 :(得分:-1)
您需要使用InsecureSkipVerify标志,请参阅https://groups.google.com/forum/#!topic/golang-nuts/c9zEiH6ixyw。
此帖子的相关代码(包含页面离线):
smtpbox := "mail.foo.com:25"
c, err := smtp.Dial(smtpbox)
host, _, _ := net.SplitHostPort(smtpbox)
tlc := &tls.Config{
InsecureSkipVerify: true,
ServerName: host,
}
if err = c.StartTLS(tlc); err != nil {
fmt.Printf(err)
os.Exit(1)
}
// carry on with rest of smtp transaction
// c.Auth, c.Mail, c.Rcpt, c.Data, etc