首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何处理证书不正确的https请求?

如何处理证书不正确的https请求?
EN

Stack Overflow用户
提问于 2012-08-25 20:57:47
回答 6查看 165.8K关注 0票数 169

假设我想以编程方式获取https://golang.org。目前,golang.org (ssl)有一个颁发给*.appspot.com的坏证书,所以当我运行以下命令时:

代码语言:javascript
复制
package main

import (
    "log"
    "net/http"
)

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

我得到了(正如我所期望的)

代码语言:javascript
复制
Get https://golang.org/: certificate is valid for *.appspot.com, *.*.appspot.com, appspot.com, not golang.org

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

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

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-08-25 22:12:30

安全说明:禁用安全检查是危险的,应该避免

您可以对默认客户端的所有请求全局禁用安全检查:

代码语言:javascript
复制
package main

import (
    "fmt"
    "net/http"
    "crypto/tls"
)

func main() {
    http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
    _, err := http.Get("https://golang.org/")
    if err != nil {
        fmt.Println(err)
    }
}

您可以禁用客户端的安全检查:

代码语言:javascript
复制
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)
    }
}
票数 348
EN

Stack Overflow用户

发布于 2017-09-02 15:02:32

正确的方式(从Go 1.13开始)(由answer below提供):

代码语言:javascript
复制
customTransport := http.DefaultTransport.(*http.Transport).Clone()
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{Transport: customTransport}

原始答案:

这里有一种方法,可以在不丢失DefaultTransport的默认设置的情况下做到这一点,并且不需要根据用户评论来伪造请求。

代码语言:javascript
复制
defaultTransport := http.DefaultTransport.(*http.Transport)

// Create new Transport that ignores self-signed SSL
customTransport := &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},
}
client := &http.Client{Transport: customTransport}

更短的方式:

代码语言:javascript
复制
customTransport := &(*http.DefaultTransport.(*http.Transport)) // make shallow copy
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{Transport: customTransport}

警告:仅用于测试/开发目的。如有其他问题,请自行承担风险!

票数 38
EN

Stack Overflow用户

发布于 2017-11-08 09:12:21

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

InsecureSkipVerify有一个合法用途:使用它连接到主机并获取其证书,然后立即断开连接。如果您将代码设置为使用InsecureSkipVerify,通常是因为您没有正确设置ServerName (它将需要来自env var或其他东西-不要对此要求感到厌烦……正确地做它)。

特别是,如果您使用客户端证书并依赖于它们进行身份验证,那么您基本上就有了一个不再实际登录的假登录。拒绝执行InsecureSkipVerify的代码,否则您将以很难的方式了解它的错误所在!

票数 25
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12122159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档