简体   繁体   English

Windows:Python SSL 证书验证失败

[英]Windows: Python SSL certificate verify failed

I've installed Anaconda and had SSL problems when trying to do API calls via Jupyter Notebooks:我已经安装了 Anaconda 并且在尝试通过 Jupyter Notebooks 进行 API 调用时遇到了 SSL 问题:

import requests
import certifi

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

This first produced a SSL connection error.这首先产生了 SSL 连接错误。 Which I could solve after extensive search and the help of our IT department.经过广泛的搜索和我们 IT 部门的帮助,我可以解决这个问题。 The solution here was to add the company root certificate to certifi cert storage.这里的解决方案是将公司根证书添加到 certifi 证书存储中。

Now for other requests unfortunately I still have the same problems.现在对于其他请求,不幸的是我仍然遇到同样的问题。 Example code calling the Google Analytics API with google2pandas package:使用 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)

Here I still get the SSL error I had on the simple call before as well:在这里,我仍然收到我之前在简单调用中遇到的 SSL 错误:

C:\\ProgramData\\Anaconda3\\lib\\ssl.py in _create(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session) 848 # non-blocking 849 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets") --> 850 self.do_handshake() 851 except (OSError, ValueError): 852 self.close() C:\\ProgramData\\Anaconda3\\lib\\ssl.py in _create(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session) 848 # 非阻塞 849 raise ValueError("do_handshake_on_connect should not be specified for non-blocking套接字”)--> 850 self.do_handshake() 851 除了(OSError,ValueError):852 self.close()

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

SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1045) SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获得本地颁发者证书 (_ssl.c:1045)

I believe there is another library in use, that doesn't rely on certifi?我相信还有另一个库在使用,它不依赖于证书? But I don't have any idea on where and how to add my root certificate, so all iPython requests will work.但是我不知道在何处以及如何添加我的根证书,因此所有 iPython 请求都将起作用。

Any ideas are appreciated.任何想法表示赞赏。

I spent a few days figuring out how to solve this problem.我花了几天时间想出如何解决这个问题。 Finally I add the CA certificate of my company in a configuration file used by requests library.最后,我将我公司的 CA 证书添加到请求库使用的配置文件中。 You can check the path of this file by:您可以通过以下方式检查此文件的路径:

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

The path of the cacert.pem that python uses shall be printed, edit it and append the CA certificate to the bottom of it.打印python使用的cacert.pem的路径,编辑并在其底部附加CA证书。

You can monkey-patch the __init__ method of ssl.SSLSocket so that it always ignores SSL certificate verification by forcing the cert_reqs=CERT_NONE parameter.您可以对ssl.SSLSocket__init__方法进行猴子补丁,以便它通过强制cert_reqs=CERT_NONE参数始终忽略 SSL 证书验证。

Add this to the beginning of your script:将此添加到脚本的开头:

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)

I've made progress.我取得了进步。 httplib2 is the package, that caused the problems. httplib2 是导致问题的包。 It has it's own cacerts.txt, where I added the root certificate as well now.它有自己的 cacerts.txt,我现在也在其中添加了根证书。

Cheers,干杯,

Andreas安德烈亚斯

The above solution is not very suitable due to security reasons.由于安全原因,上述解决方案不是很合适。 A better solution for this problem is:这个问题的一个更好的解决方案是:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM