【发布时间】:2020-02-14 21:27:35
【问题描述】:
我正在尝试使用 golang http/tsl 客户端通过 SSL/TLS 连接到服务器,这会导致“Handshake Faliure(40)”错误,但由于某种原因,这个相同的端点适用于 CURL 命令。经过一番调试,我收集到如下数据。
func PrepCerts(certMap map[string]string) (*http.Transport, bool) {
ok := false
tlsConfig := &tls.Config{}
if len(certMap["ca"]) > 0 {
caCert, err := ioutil.ReadFile(certMap["ca"])
fmt.Println("caCert : ", caCert)
if err != nil {
log.Fatal(err)
} else {
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
(*tlsConfig).RootCAs = caCertPool
ok = true
}
}
if len(certMap["cert"]) > 0 && len(certMap["key"]) > 0 {
cert, err := tls.LoadX509KeyPair(certMap["cert"], certMap["key"])
fmt.Println("cert : ", cert)
if err != nil {
log.Fatal(err)
} else {
(*tlsConfig).Certificates = []tls.Certificate{cert}
ok = true
}
}
tlsConfig.BuildNameToCertificate()
return &http.Transport{TLSClientConfig: tlsConfig}, ok
}
使用上述函数的代码
client := &http.Client{
Timeout: timeout,
}
//certMap = map[string]string{
// ca : "filelocation",
// cert : "filelocation",
// key " "filelocation",
//}
if transport, ok := PrepCerts(certMap); ok {
(*client).Transport = transport
}
resp, err := client.Do(req)
【问题讨论】:
-
"大密码,请!"如果我们看不到正在发生的事情,我们甚至应该如何开始验证和验证。握手失败 40 似乎表明服务器和客户端无法就密码套件达成一致。奇怪...
-
@MarkusWMahlberg - “服务器问候”数据包(第 5 张图片)表示他们同意 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384。如果您需要,我仍然可以添加代码?
-
@MarkusWMahlberg - 我添加了代码,希望对您有所帮助。
-
@MarkusWMahlberg:“握手失败 40 似乎表明服务器和客户端无法就密码套件达成一致” - 警报 40 只是一般的“握手失败”。当找不到共享密码时,它通常从服务器发送到客户端,因为没有特定的警报类型,但不限于这种情况。见RFC 5246 section 7.2。
-
如果客户端从证书请求中发送了 0 个证书,则意味着没有兼容的签名方案,或者证书不是由可接受的 CA 之一颁发的。检查证书请求信息的最简单方法是使用
GetClientCertificate加载证书。