我正在使用Ebay Trading APIs消费Ebay python sdk,python-requests最终会点cacert.pem file进行API调用。
一切都很好,但是从最近几天起我无法拨打电话。我收到了错误:
SSLError: bad handshake: Error([('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')],)
这是完整的追溯:
In [9]: response = api.execute('GetSessionID', data)
---------------------------------------------------------------------------
SSLError Traceback (most recent call last)
<ipython-input-9-eb33610c2a7f> in <module>()
----> 1 response = api.execute('GetSessionID', data)
/home/debian/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/ebaysdk/connection.pyc in execute(self, verb, data, list_nodes, verb_attrs, files)
117
118 self.build_request(verb, data, verb_attrs, files)
--> 119 self.execute_request()
120
121 if hasattr(self.response, 'content'):
/home/debian/.virtualenvs/goplaces/local/lib/python2.7/site-packages/ebaysdk/connection.pyc in execute_request(self)
182 proxies=self.proxies,
183 timeout=self.timeout,
--> 184 allow_redirects=True
185 )
186
/home/debian/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/requests/sessions.pyc in send(self, request, **kwargs)
574
575 # Send the request
--> 576 r = adapter.send(request, **kwargs)
577
578 # Total elapsed time of the request (approximately)
/home/debian/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/requests/adapters.pyc in send(self, request, stream, timeout, verify, cert, proxies)
431 except (_SSLError, _HTTPError) as e:
432 if isinstance(e, _SSLError):
--> 433 raise SSLError(e, request=request)
434 elif isinstance(e, ReadTimeoutError):
435 raise ReadTimeout(e, request=request)
SSLError: bad handshake: Error([('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')],)
StackOverflow上有很多相关的问题,所有这些都说:
我不能这样做是因为:
此外,
我不知道为什么会这样。
当我禁用SSL3时,为什么SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed'
处于追溯状态。 (我对SSL没有深入了解。)
谢谢!
# openssl version
OpenSSL 1.0.2e 3 Dec 2015
在@Steffen Ullrich的建议之后,从源头构建,从1.0.1升级到openssl 1.0.2。
$ pip freeze | grep -i ssl
backports.ssl-match-hostname==3.4.0.2
pyOpenSSL==0.15.1
答案 0 :(得分:2)
我的猜测是这与Python Urllib2 SSL error有关,即OpenSSL底层实现中存在多个信任路径的问题。在那里查看问题的详细信息。
要修复此问题而不更改您的可信CA,您需要有一个固定的OpenSSL,即OpenSSL 1.0.2。或者您可以将一些旧的CA证书添加回您的信任存储区。
- 传递参数verify = False
- 通过CA证书
- 在cacert.pem文件中附加CA证书(我试过这个,但没有用)
醇>... 从安全角度来看这是不好的。
虽然verify=False
对安全性有害,但因为它禁用了验证,其他选项也不错,因为它们只添加了额外的信任锚,但仍然启用了验证。
当我禁用SSL3时,为什么SSL例程','SSL3_GET_SERVER_CERTIFICATE','证书验证失败'处于追溯状态。
即使它谈到SSLv3,也不代表它。 TLS和SSLv3共享许多功能,即TLS 1.0实际上是SSL 3.1。因此,OpenSSL代码中的许多SSL3_*
函数也与TLS 1.x一起使用,这会导致这些恼人的消息。
答案 1 :(得分:0)
我认为它与https://pypi.python.org/pypi/certifi/
的这一部分有关1024位根证书
浏览器和证书颁发机构 得出的结论是,1024位密钥对于证书来说是不可接受的, 特别是根证书。出于这个原因,Mozilla已经删除了 来自其捆绑包的任何弱(即1024位密钥)证书,替换它 具有等效的强(即2048位或更高的密钥)证书 来自同一个CA.因为Mozilla从其中删除了这些证书 捆绑,certifi也删除了它们。
不幸的是,旧版本的OpenSSL(小于1.0.2)有时候 无法验证使用强根的证书链。对于 这个原因,如果您无法使用该证书验证证书 certifi.where()机制,你可以故意重新添加1024位 通过调用certifi.old_where()来回到你的包中。 这不建议在生产中使用:如果可能的话,你应该这样做 升级到更新的OpenSSL。但是,如果您没有其他选择,请执行此操作 可能适合你。
我的测试是这样的:
root@43b7ec35c240:/usr/src/app# cat /etc/debian_version
8.2
root@43b7ec35c240:/usr/src/app# cat test.py
import logging
import requests
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
requests.get('https://www.google.com/')
root@43b7ec35c240:/usr/src/app# python test.py
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.google.com
DEBUG:requests.packages.urllib3.connectionpool:"GET / HTTP/1.1" 302 263
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.google.com.hk
DEBUG:requests.packages.urllib3.connectionpool:"GET /?gfe_rd=cr&ei=XXKbVqqBD8WM8Qe3v7-YAQ HTTP/1.1" 200 None
root@43b7ec35c240:/usr/src/app# openssl version
OpenSSL 1.0.1k 8 Jan 2015
root@43b7ec35c240:/usr/src/app# pip install certifi
Collecting certifi
Using cached certifi-2015.11.20.1-py2.py3-none-any.whl
Installing collected packages: certifi
Successfully installed certifi-2015.11.20.1
root@43b7ec35c240:/usr/src/app# python test.py
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.google.com
Traceback (most recent call last):
File "test.py", line 16, in <module>
requests.get('https://www.google.com/')
File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 69, in get
return request('get', url, params=params, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 468, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 576, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/adapters.py", line 433, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)
root@43b7ec35c240:/usr/src/app# pip uninstall certifi
Uninstalling certifi-2015.11.20.1:
/usr/local/lib/python2.7/site-packages/certifi-2015.11.20.1.dist-info/DESCRIPTION.rst
/usr/local/lib/python2.7/site-packages/certifi-2015.11.20.1.dist-info/METADATA
/usr/local/lib/python2.7/site-packages/certifi-2015.11.20.1.dist-info/RECORD
/usr/local/lib/python2.7/site-packages/certifi-2015.11.20.1.dist-info/WHEEL
/usr/local/lib/python2.7/site-packages/certifi-2015.11.20.1.dist-info/metadata.json
/usr/local/lib/python2.7/site-packages/certifi-2015.11.20.1.dist-info/top_level.txt
/usr/local/lib/python2.7/site-packages/certifi/__init__.py
/usr/local/lib/python2.7/site-packages/certifi/__init__.pyc
/usr/local/lib/python2.7/site-packages/certifi/__main__.py
/usr/local/lib/python2.7/site-packages/certifi/__main__.pyc
/usr/local/lib/python2.7/site-packages/certifi/cacert.pem
/usr/local/lib/python2.7/site-packages/certifi/core.py
/usr/local/lib/python2.7/site-packages/certifi/core.pyc
/usr/local/lib/python2.7/site-packages/certifi/old_root.pem
/usr/local/lib/python2.7/site-packages/certifi/weak.pem
Proceed (y/n)? y
Successfully uninstalled certifi-2015.11.20.1
root@43b7ec35c240:/usr/src/app# python test.py
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.google.com
DEBUG:requests.packages.urllib3.connectionpool:"GET / HTTP/1.1" 302 263
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.google.com.hk
DEBUG:requests.packages.urllib3.connectionpool:"GET /?gfe_rd=cr&ei=AnObVtG4BcGM8QeC6r-YCw HTTP/1.1" 200 None
然后我尝试通过执行以下操作来更新我的libssl包:
# curl http://apt.wikimedia.org/autoinstall/keyring/wikimedia-archive-keyring.gpg | apt-key add -
# echo "deb http://apt.wikimedia.org/wikimedia jessie-wikimedia backports" >> /etc/apt/sources.list
# apt-get update
# apt-get install libssl1.0.0
# openssl version
OpenSSL 1.0.1k 8 Jan 2015 (Library: OpenSSL 1.0.2e 3 Dec 2015)
在那之后,即使安装了certifi,我也很好。
# pip freeze |grep certifi
certifi==2015.11.20.1
# python test.py
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.google.com
DEBUG:requests.packages.urllib3.connectionpool:"GET / HTTP/1.1" 302 263
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.google.com.hk
DEBUG:requests.packages.urllib3.connectionpool:"GET /?gfe_rd=cr&ei=4XSbVt2gK8OM8Qe1tICIBA HTTP/1.1" 200 None