【问题标题】:Python request SSLError: bad handshake on https://gcm-http.googleapis.com [duplicate]Python请求SSLError:https://gcm-http.googleapis.com上的握手错误[重复]
【发布时间】:2017-07-14 19:40:02
【问题描述】:

尝试向 GCM API 发出 Python 请求,但未验证证书。

请求和证书包已更新

  • Python 2.7.6
  • 证书==2017.4.17
  • 请求==2.18.1
  • pyOpenSSL==17.1.0

尝试调用其他服务器,返回都OK:

错误消息:错误的握手:Error([('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')],)

【问题讨论】:

  • 错误握手通常与证书验证无关,但更多与 TLS 协议版本不匹配、密码、缺少 SNI、缺少客户端证书或类似情况有关。
  • @SteffenUllrich 我已经更新了确切的错误消息。问题不在于证书“验证”,而在于验证。顺便说一句,你是对的,与证书验证无关。证书可能有效,但程序无法验证。
  • 谢谢。尽可能获得最详细的错误描述总是好的。基于此,我很确定这是我为重复添加的问题中的确切问题,即您的旧 OpenSSL 版本的问题与替代链验证结合缺少您商店中的旧根证书。 @bpscott 使用 certifi.old_where() 的建议可能有助于解决此问题。

标签: python ssl google-api


【解决方案1】:

我在研究这个问题时遇到了一些有趣的结果。在我看来,这可能是问题所在。告诉我。

TL;DR

尝试使用certifi.old_where()。如果这可行,那么您确实应该在您的服务器上升级到更新版本的 OpenSSL。

来源

GitHub:

https://github.com/certifi/python-certifi/issues/32

来自@Lukasa

您能否确认这是否与#26 相同的问题?也就是说,尝试将 certifi.old_where() 传递给请求的验证参数。

...

需要明确的是,除了使用 certifi.old_where() 或升级 OpenSSL 之外,Python 领域没有解决此问题的方法。您系统上的 OpenSSL 太旧,无法正确验证交叉签名的 TLS 证书,而且我无法解决三个问题。如果您使用 certifi.old_where(),您的系统将面临重大风险,因为您继续将信任建立在 1024 位 RSA 证书上,该证书自 2012 年以来已被弃用,并且已经受到多种已知攻击。

证书文件:

https://pypi.python.org/pypi/certifi

1024 位根证书

浏览器和证书颁发机构已得出结论,1024 位密钥对于证书(尤其是根证书)的脆弱性令人无法接受。出于这个原因,Mozilla 已从其捆绑包中删除了任何弱(即 1024 位密钥)证书,用来自同一 CA 的等效强(即 2048 位或更大密钥)证书替换它。因为 Mozilla 从其捆绑包中删除了这些证书,所以 certifi 也删除了它们。

很遗憾,旧版本的 OpenSSL(低于 1.0.2)有时无法验证使用强根的证书链。因此,如果您无法使用 certifi.where() 机制验证证书,您可以通过调用 certifi.old_where() 有意将 1024 位根重新添加到您的包中。不建议在生产环境中这样做:如果可能,您应该升级到更新的 OpenSSL。但是,如果您别无选择,这可能对您有用。

【讨论】:

  • certifi.old_where() 运行良好,但现在无法升级 OpenSSL。 Amazon Linux 卡在 1.0.1 上。我将更改为支持 1.0.2 的另一个发行版。谢谢。
  • 很高兴帮助您找到问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
  • 1970-01-01
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多