golang:如何做一个有错误证书的https请求?

说我想以编程方式获得https://golang.org 。 目前golang.org(SSL)有一个错误的证书发给*.appspot.com所以当我运行这个:

 package main import ( "log" "net/http" ) func main() { _, err := http.Get("https://golang.org/") if err != nil { log.Fatal(err) } } 

我得到(如我所料)

 Get https://golang.org/: certificate is valid for *.appspot.com, *.*.appspot.com, appspot.com, not golang.org 

现在,我想自己相信这个证书(想象一下我可以在哪里validation指纹等自我颁发的证书):我如何提出请求并validation/信任证书?

我可能需要使用openssl下载证书,将其加载到我的文件,并填写tls.Config结构!?

您可以禁用安全检查(风险自担):

 package main import ( "fmt" "net/http" "crypto/tls" ) func main() { tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} _, err := client.Get("https://golang.org/") if err != nil { fmt.Println(err) } } 

如果您想使用http包中的默认设置,那么您不需要创build新的Transport和Client对象,则可以更改为忽略证书validation,如下所示:

 tr := http.DefaultTransport.(*http.Transport) tr.TLSClientConfig.InsecureSkipVerify = true 

这里有一种方法可以在不失去DefaultTransport的默认设置的情况下进行,而且不需要根据用户评论的假冒请求。

 defaultTransport := http.DefaultTransport.(*http.Transport) // Create new Transport that ignores self-signed SSL httpClientWithSelfSignedTLS := &http.Transport{ Proxy: defaultTransport.Proxy, DialContext: defaultTransport.DialContext, MaxIdleConns: defaultTransport.MaxIdleConns, IdleConnTimeout: defaultTransport.IdleConnTimeout, ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout, TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout, TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } 

所有这些答案都是错误的! 不要使用InsecureSkipVerify处理与主机名不匹配的CN。 Go开发者不明智地坚持不禁止主机名检查(它具有合法的用途 – 隧道,NAT,共享集群证书等),同时也有类似的东西,但实际上完全忽略了证书检查。 您需要知道证书是有效的,并且由您信任的证书签名。 但在常见情况下,您知道CN将不会与您连接的主机名匹配。 对于那些,请在tls.Config上设置ServerName。 如果tls.Config.ServerName == remoteServerCN,那么证书检查将成功。 这是你想要的。 InsecureSkipVerify意味着没有authentication; 中东人已经成熟了; 打破了使用TLS的目的。

有一个合法使用InsecureSkipVerify …使用它来连接到主机,并获取其证书,然后立即断开连接。 如果你设置你的代码来使用InsecureSkipVerify,通常是因为你没有正确设置ServerName(它将需要来自env var或其他东西 – 不要肚子疼这个要求…做得正确)。

特别是,如果您使用客户端证书并依靠它们进行身份validation,则基本上会有一个虚假的login,实际上不会再login。 拒绝InsecureSkipVerify的代码,否则您将难以学习到什么是错误的!