ssl - Golang 证书验证

标签 ssl go cryptography x509

我正在使用 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 在那里(根本没有名字,如错误状态),但我看不到我是怎么做到的错了。

我应该如何解决这个问题?

最佳答案

你需要做两件事:

  1. 同时在服务器端添加CA证书,CA需要各方都知道。
  2. 在服务器上生成并使用服务器证书(证书中包含主机名)。服务器证书需要由 CA 签名。

您可以在 here 找到这方面的示例(第一个谷歌示例)

编辑:澄清一下,错误是由于您正在尝试安全地连接到远程主机。默认情况下,go 客户端将查找服务器返回的有效证书。

有效手段(除其他外):

  1. 由已知的 CA 签名
  2. 它在 CommonNameSubject Alternative Name 中包含服务器的 ip/dns(您传递给 http.NewRequest 的服务器):DNS/IP 字段。

最终编辑:

服务器证书包含设置为服务器主机名的正确Common Name,但它还包含设置为电子邮件地址的Subject Alternative Name

https://groups.google.com/a/chromium.org/forum/#!topic/security-dev/IGT2fLJrAeo 中所述,如果找到 SAN,Go 现在会忽略 Common Name

关于ssl - Golang 证书验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47734147/

相关文章:

security - 一种以上加密算法的组合

php - 如何在 PHP CURL 中使用 ECDHE 密码?

Apache2.4 - SSL 证书安装不工作

c# - WCF 休息服务 http 到 https 错误 404

java - 将字节 slice 中的负数转换为 int

google-app-engine - 如何在谷歌应用引擎中存储服务器的私钥?

c - ECC 反模奇异时间执行

security - https不需要加密数据?

go - 使用 Go 语言简单 HTTP 服务器打印到日志

.net - 如何解密用 HMACSHA1 加密的字符串?