doubao12345 2017-12-09 23:01
浏览 320
已采纳

Golang证书验证

I'm using Go to perform HTTPS requests with a custom root CA. The root CA is the only certificate I have on my side.

My code looks like this:

// 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)
}

The error I get back is this:

2017/12/09 21:06:13 Post https://secure.site: x509: certificate is not valid for any names, but wanted to match secure.site

I've been unable to find out exactly what the cause is of this. When checking the SANs of the CA cert, I don't have secure.site in there (no names at all, as the error states), but I can't see how I've done this wrong.

What should I do to troubleshoot this?

  • 写回答

1条回答 默认 最新

  • dongxiangchan0743 2017-12-09 23:06
    关注

    You need to do two things:

    1. add the CA certificate on the server side as well, the CA needs to be known by all parties.
    2. generate and use a server certificate (with the hostname in the certificate) on the server. The server cert needs to be signed by the CA.

    You can find an example of this at here (first google example)

    Edit: to clarify, the error is due to the fact that you are trying to connect securely to a remote host. By default, the go client will look for a valid certificate returned by the server.

    Valid means (among other things):

    1. it is signed by a known CA
    2. it contains the ip/dns of the server (the one you passed to http.NewRequest) in the CommonName or Subject Alternative Name: DNS/IP fields.

    final edit:

    The server certificate contained the correct Common Name set to the server hostname, but it also contained a Subject Alternative Name set to an email address.

    As mentioned in https://groups.google.com/a/chromium.org/forum/#!topic/security-dev/IGT2fLJrAeo, Go now ignores the Common Name if is a SAN is found.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号