英文:
Go TLS connection
问题
我通过openssl连接到了某个服务器:
openssl s_client -crlf -connect somehost.com:700 -cert key.pem
它可以正常工作,连接成功。
但是当我尝试使用Go代码进行相同的操作时(来自文档的示例),它对我来说不起作用:
import (
"crypto/tls"
"crypto/x509"
)
func main() {
// 使用自定义根证书集进行连接。
const rootPEM = `
-----BEGIN CERTIFICATE-----
我的密钥文本
-----END CERTIFICATE-----`
// 首先,创建根证书集。在这个示例中,我们只有一个根证书。也可以省略这一步,以使用当前操作系统的默认根证书集。
roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM([]byte(rootPEM))
if !ok {
panic("无法解析根证书")
}
conn, err := tls.Dial("tcp", "somehost.com:700", &tls.Config{
RootCAs: roots,
})
if err != nil {
panic("连接失败:" + err.Error())
}
conn.Close()
}
我的错误信息是:
panic: 连接失败:x509: 证书有效期为 otherhost.com,而不是 somehost.com [已恢复]
问题:我做错了什么?也许我没有添加一些tls.Config参数?
英文:
I connect to some server via openssl:
openssl s_client -crlf -connect somehost.com:700 -cert key.pem
And it works. Connection is successful.
But when I tried to do same from Go code (example from documentation), it doesn't work for me:
import (
"crypto/tls"
"crypto/x509"
)
func main() {
// Connecting with a custom root-certificate set.
const rootPEM = `
-----BEGIN CERTIFICATE-----
my key text
-----END CERTIFICATE-----`
// First, create the set of root certificates. For this example we only
// have one. It's also possible to omit this in order to use the
// default root set of the current operating system.
roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM([]byte(rootPEM))
if !ok {
panic("failed to parse root certificate")
}
conn, err := tls.Dial("tcp", "somehost.com:700", &tls.Config{
RootCAs: roots,
})
if err != nil {
panic("failed to connect: " + err.Error())
}
conn.Close()
}
My text error is:
panic: failed to connect: x509: certificate is valid for otherhost.com, not somehost.com [recovered]
Question: what did I do wrong? And maybe I didn't add some tls.Config parameters?
答案1
得分: 2
openssl s_client
只是一个测试工具,它只是连接,对于证书是否有效并不太关心。而Go语言则会验证证书是否可验证,所以你会得到证书无效的信息,因为名称不匹配。
我做错了什么?
根据错误信息,你可能是通过错误的主机名访问了主机。或者你配置了服务器,以致它发送了错误的证书。
英文:
openssl s_client
is just a test tool which connects but it does not care much if the certificate is valid for the connection. Go instead cares if the certificate could be validated, so you get the information that the certificate is invalid because the name does not match.
> what did I do wrong?
Based on the error message you did access the host by the wrong hostname. Or you've configured your server badly so that it sends the wrong certificate.
答案2
得分: 0
我不需要检查服务器的 SSL 证书。它是某个域名注册处的演示服务器。所以我需要服务器来检查我的证书。
const certPEM = `-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
`
const certKey = `-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----`
cert, err := tls.X509KeyPair([]byte(certPEM), []byte(certKey))
if err != nil {
t.Error("server: loadkeys: %s", err)
}
cfg := tls.Config{
InsecureSkipVerify: true,
ServerName: "somehost.com",
Certificates: []tls.Certificate{cert},
}
conn, err := tls.Dial("tcp", "somehost.com:700", &cfg)
if err != nil {
t.Error("failed to connect: " + err.Error())
}
defer conn.Close()
所以这段代码在我的情况下是有效的。
英文:
I didn't need to check ssl certificate of server. It was demo server of some domain registry. So I need server to check my certificate.
const certPEM = `-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
`
const certKey = `-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----`
cert, err := tls.X509KeyPair([]byte(certPEM), []byte(certKey))
if err != nil {
t.Error("server: loadkeys: %s", err)
}
cfg := tls.Config{
InsecureSkipVerify: true,
ServerName: "somehost.com",
Certificates: []tls.Certificate{cert},
}
conn, err := tls.Dial("tcp", "somehost.com:700", &cfg)
if err != nil {
t.Error("failed to connect: " + err.Error())
}
defer conn.Close()
So this code works in my case.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论