Golang 证书验证
Golang certificate validation
我正在使用 Go 通过自定义根 CA 执行 HTTPS 请求。根 CA 是我这边唯一的证书。
我的代码如下所示:
// performRequest sets up the HTTPS Client we'll use for communication and handle the actual requesting to the external
// end point. It is used by the auth and collect adapters who set their response data up first.
func performRequest(rawData []byte, soapHeader string) (*http.Response, error) {
conf := config.GetConfig()
// Set up the certificate handler and the HTTP client.
certPool := x509.NewCertPool()
certPool.AppendCertsFromPEM(certificate)
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
InsecureSkipVerify: false,
},
},
}
req, err := http.NewRequest(http.MethodPost, baseURL, bytes.NewBuffer(rawData))
if err != nil {
return nil, err
}
// Sets the SOAPAction and Content-Type headers to the request.
req.Header.Set("SOAPAction", soapHeader)
req.Header.Set("Content-Type", "text/xml; charset=UTF-8")
// Send request as our custom client, return response
return client.Do(req)
}
我得到的错误是这样的:
2017/12/09 21:06:13 Post https://secure.site: x509: certificate is not valid for any names, but wanted to match secure.site
我一直无法查明这是什么原因。当检查 CA 证书的 SAN 时,我没有 secure.site
在那里(根本没有名字,如错误状态),但我看不出我是怎么做错的。
我应该如何解决这个问题?
你需要做两件事:
- 服务器端也添加CA证书,CA需要各方都知道
- 在服务器上生成并使用服务器证书(证书中包含主机名)。服务器证书需要由 CA 签名。
您可以在 here 找到这方面的示例(第一个 google 示例)
编辑:澄清一下,错误是由于您正在尝试安全地连接到远程主机。默认情况下,go 客户端会查找服务器返回的有效证书。
有效手段(除其他外):
- 它由已知的 CA 签名
- 它在
CommonName
或 Subject Alternative Name: DNS/IP
字段中包含服务器(您传递给 http.NewRequest
的服务器)的 ip/dns。
最终编辑:
服务器证书包含设置为服务器主机名的正确 Common Name
,但它还包含设置为电子邮件地址的 Subject Alternative Name
。
如 https://groups.google.com/a/chromium.org/forum/#!topic/security-dev/IGT2fLJrAeo 中所述,Go 现在忽略 Common Name
如果找到 SAN。
我正在使用 Go 通过自定义根 CA 执行 HTTPS 请求。根 CA 是我这边唯一的证书。
我的代码如下所示:
// performRequest sets up the HTTPS Client we'll use for communication and handle the actual requesting to the external
// end point. It is used by the auth and collect adapters who set their response data up first.
func performRequest(rawData []byte, soapHeader string) (*http.Response, error) {
conf := config.GetConfig()
// Set up the certificate handler and the HTTP client.
certPool := x509.NewCertPool()
certPool.AppendCertsFromPEM(certificate)
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
InsecureSkipVerify: false,
},
},
}
req, err := http.NewRequest(http.MethodPost, baseURL, bytes.NewBuffer(rawData))
if err != nil {
return nil, err
}
// Sets the SOAPAction and Content-Type headers to the request.
req.Header.Set("SOAPAction", soapHeader)
req.Header.Set("Content-Type", "text/xml; charset=UTF-8")
// Send request as our custom client, return response
return client.Do(req)
}
我得到的错误是这样的:
2017/12/09 21:06:13 Post https://secure.site: x509: certificate is not valid for any names, but wanted to match secure.site
我一直无法查明这是什么原因。当检查 CA 证书的 SAN 时,我没有 secure.site
在那里(根本没有名字,如错误状态),但我看不出我是怎么做错的。
我应该如何解决这个问题?
你需要做两件事:
- 服务器端也添加CA证书,CA需要各方都知道
- 在服务器上生成并使用服务器证书(证书中包含主机名)。服务器证书需要由 CA 签名。
您可以在 here 找到这方面的示例(第一个 google 示例)
编辑:澄清一下,错误是由于您正在尝试安全地连接到远程主机。默认情况下,go 客户端会查找服务器返回的有效证书。
有效手段(除其他外):
- 它由已知的 CA 签名
- 它在
CommonName
或Subject Alternative Name: DNS/IP
字段中包含服务器(您传递给http.NewRequest
的服务器)的 ip/dns。
最终编辑:
服务器证书包含设置为服务器主机名的正确 Common Name
,但它还包含设置为电子邮件地址的 Subject Alternative Name
。
如 https://groups.google.com/a/chromium.org/forum/#!topic/security-dev/IGT2fLJrAeo 中所述,Go 现在忽略 Common Name
如果找到 SAN。