【问题标题】:Windows: Python SSL certificate verify failedWindows:Python SSL 证书验证失败
【发布时间】:2019-03-23 01:44:22
【问题描述】:

我安装了 Anaconda,但在尝试通过 Jupyter Notebooks 进行 API 调用时遇到了 SSL 问题:

import requests
import certifi

r = requests.get('https://github.com/')
print(r)

这首先产生了 SSL 连接错误。经过广泛的搜索和我们 IT 部门的帮助,我可以解决这个问题。这里的解决方案是将公司根证书添加到证书存储中。

不幸的是,现在对于其他请求,我仍然遇到同样的问题。使用 google2pandas 包调用 Google Analytics API 的示例代码:

from google2pandas import *

query = {
    'reportRequests': [{
        'viewId' : 37616054,

        'dateRanges': [{
            'startDate' : '8daysAgo',
            'endDate'   : 'today'}],

        'dimensions' : [
            {'name' : 'ga:date'}, 
            {'name' : 'ga:pagePath'},
            {'name' : 'ga:browser'}],

        'metrics'   : [
            {'expression' : 'ga:pageviews'}],

        'dimensionFilterClauses' : [{
            'operator' : 'AND',
            'filters'  : [
                {'dimensionName' : 'ga:browser',
                 'operator' : 'REGEXP',
                 'expressions' : ['Firefox']},

                {'dimensionName' : 'ga:pagePath',
                 'operator' : 'REGEXP',
                 'expressions' : ['iPhone']}]
        }]
    }]
}

# Assume we have placed our client_secrets_v4.json file in the current
# working directory.

conn = GoogleAnalyticsQueryV4(secrets='Analytics.json')
df = conn.execute_query(query)

在这里,我仍然遇到之前在简单调用中遇到的 SSL 错误:

C:\ProgramData\Anaconda3\lib\ssl.py 在 _create(cls, sock, server_side, do_handshake_on_connect、suppress_ragged_eofs、server_hostname、 上下文,会话) 第848章 第849章 非阻塞套接字") --> 850 self.do_handshake() 851 除了(OSError,ValueError): 第852章

C:\ProgramData\Anaconda3\lib\ssl.py in do_handshake(self, block)
1106 如果超时 == 0.0 并且阻塞:1107
self.settimeout(无) -> 1108 self._sslobj.do_handshake() 1109 最后:1110 self.settimeout(timeout)

SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书 验证失败:无法获取本地颁发者证书 (_ssl.c:1045)

我相信还有另一个库正在使用,它不依赖于证书?但是我不知道在哪里以及如何添加我的根证书,所以所有 iPython 请求都可以工作。

感谢任何想法。

【问题讨论】:

  • 当您调用 GoogleAnalytics API 时,作为 SSL 握手的一部分,它会出示它的证书。您需要出示证书的颁发者证书才能通过握手。因此,您需要获取它并将其添加到您的商店中。
  • 嗨@Jay,感谢您的回复。不幸的是,我不完全理解答案。我确实将公司根证书添加到证书中。我是否需要将其添加到第二家商店以进行握手验证?一般来说,我对 SSL 知之甚少。在我们公司网络之外,来自 Python 库的相同请求可以正常工作。

标签: python api ssl get


【解决方案1】:

您可以对ssl.SSLSocket__init__ 方法进行猴子补丁,使其始终通过强制cert_reqs=CERT_NONE 参数忽略SSL 证书验证。

将此添加到脚本的开头:

import ssl
orig_sslsocket_init = ssl.SSLSocket.__init__
ssl.SSLSocket.__init__ = lambda *args, cert_reqs=ssl.CERT_NONE, **kwargs: orig_sslsocket_init(*args, cert_reqs=ssl.CERT_NONE, **kwargs)

【讨论】:

  • 谢谢,但这意味着通过 SSL 不再安全,对吧?
  • 对。使用此选项,连接仍将通过 SSL 加密,但不会验证证书。如果您无法安装正确的根证书,请使用此方法。
【解决方案2】:

我已经取得了进步。 httplib2 是导致问题的包。它有自己的 cacerts.txt,我现在也在其中添加了根证书。

干杯,

安德烈亚斯

【讨论】:

    【解决方案3】:

    我花了几天时间想办法解决这个问题。最后,我将我公司的 CA 证书添加到请求库使用的配置文件中。您可以通过以下方式检查此文件的路径:

    import requests as r
    print(r.certs.where())
    

    将python使用的cacert.pem的路径打印出来,编辑并在底部附加CA证书。

    【讨论】:

    • 你能告诉底部在哪里吗?我有来自 print(r.certs.where()) 的 .pem 文件,并使用了 r = requests.get("mycompany.com/home", cert="C:/.../site-packages/certifi/cacert. pem") 。仍然出现与上述相同的错误
    • 使用文本编辑器打开您找到的 .pem 文件,滚动到文件底部并粘贴您的证书
    • 成功了,非常感谢!看起来也可以覆盖 certifi.core.where 函数以使其使用您的公司证书文件并避免编辑(我想分发解决方案更好)在此处查看详细信息stackoverflow.com/a/47699138/2787591
    【解决方案4】:

    由于安全原因,上述解决方案不是很合适。这个问题的一个更好的解决方案是:

    【讨论】:

      【解决方案5】:

      一种可能的解决方案是指示 Python 使用您的 Windows 证书存储而不是 certifi 包中的内置存储。您可以通过安装 python-certifi-win32 来做到这一点:

      pip install python-certifi-win32
      

      Python 使用与浏览器相同的证书。

      【讨论】:

      • 这个解决方案只需要 9 个小时就可以帮助我。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 2021-10-08
      • 2016-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多