问题描述
问题
我一直在尝试使用Python的requests包下载如下网址:
但是,在 Python 中,请求失败并显示 SSLV3_ALERT_HANDSHAKE_FAILURE
,即使 使用忽略错误证书的 verify
标志:
如果您将 verify 设置为 False,请求也可以忽略验证 SSL 证书
堆栈跟踪
>>>请求.__版本__'2.7.0'>>>LOGIN_URL = 'https://service.isracard.co.il/I_logon.jsp'>>>requests.get(LOGIN_URL, 验证=假)回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中文件/private/tmp/sslenv/lib/python2.7/site-packages/requests/api.py",第 69 行,在 get返回请求('get', url, params=params, **kwargs)文件/private/tmp/sslenv/lib/python2.7/site-packages/requests/api.py",第 50 行,请求response = session.request(method=method, url=url, **kwargs)文件/private/tmp/sslenv/lib/python2.7/site-packages/requests/sessions.py",第 465 行,请求resp = self.send(prep, **send_kwargs)文件/private/tmp/sslenv/lib/python2.7/site-packages/requests/sessions.py",第573行,发送r = adapter.send(request, **kwargs)文件/private/tmp/sslenv/lib/python2.7/site-packages/requests/adapters.py",第431行,发送引发 SSLError(e, request=request)requests.exceptions.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 警报握手失败 (_ssl.c:590)环境
操作系统和软件包
我在 OSX 的虚拟环境中使用 requests 2.7.0 和 Python 2.7.10.
卷曲
在同一台机器上调用相同 URL 的 cURL 工作正常:
$ curl -I https://service.isracard.co.il/I_logon.jspHTTP/1.1 200 正常日期:2015 年 9 月 18 日星期五 11:37:27 GMT服务器:IBM_HTTP_ServerX-Powered-By: Servlet/3.0设置-Cookie:JSESSIONID=0000R90MxFKBVxBMV665syGfjnh:-1;路径=/;仅Http到期:1994 年 12 月 1 日星期四 16:00:00 GMT缓存控制:no-cache="set-cookie, set-cookie2"设置-Cookie:Alt50_ZLinuxPrd=94742720.30755.0000;到期=周五,2015 年 9 月 18 日 12:07:19 GMT;路径=/内容类型:文本/html;字符集=ISO-8859-8内容语言:iw-IL设置-Cookie:ServiceP=53323968.20480.0000;路径=/
证书验证没有失败,所以 verify
参数在这里不适用.失败的是密码协商;requests
愿意使用的密码都不匹配服务器愿意使用的密码.
如果您使用 -v
开关运行您的 curl
命令,您将看到 curl
协商成功连接的密码套件:
$ curl -v -I https://service.isracard.co.il/I_logon.jsp* 在 DNS 缓存中未找到主机名* 正在尝试 192.118.12.8...* 连接到 service.isracard.co.il (192.118.12.8) 端口 443 (#0)* TLS 1.2 连接使用 TLS_RSA_WITH_RC4_128_SHA[……]
那是 RC4-SHA 密码,它有一些相当麻烦的安全问题,不应该真正使用;例如,它不提供转发保密.urllib3
包(与 requests
捆绑在一起)默认从默认密码中排除该密码.您可以将其添加回:
导入请求requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':RC4-SHA'尝试:requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST += ':RC4-SHA'除了属性错误:# 没有使用/需要/可用的pyopenssl支持经过
并且您的请求有效:
>>>进口请求>>>requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':RC4-SHA'>>>requests.get('https://service.isracard.co.il/I_logon.jsp')<响应[200]>我没有安装 pyOpenSSL 包,所以我没有打扰 try..except
保护部分.
The problem
I have been trying to use Python's requests package to download the following URL:
In Chrome, the certificate seems valid:
However, in Python, the request fails with SSLV3_ALERT_HANDSHAKE_FAILURE
, even when using the verify
flag which ignores erroneous certificates:
Stack trace
>>> requests.__version__
'2.7.0'
>>> LOGIN_URL = 'https://service.isracard.co.il/I_logon.jsp'
>>> requests.get(LOGIN_URL, verify=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/private/tmp/sslenv/lib/python2.7/site-packages/requests/api.py", line 69, in get
return request('get', url, params=params, **kwargs)
File "/private/tmp/sslenv/lib/python2.7/site-packages/requests/api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "/private/tmp/sslenv/lib/python2.7/site-packages/requests/sessions.py", line 465, in request
resp = self.send(prep, **send_kwargs)
File "/private/tmp/sslenv/lib/python2.7/site-packages/requests/sessions.py", line 573, in send
r = adapter.send(request, **kwargs)
File "/private/tmp/sslenv/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:590)
Environment
OS And packages
I'm using requests 2.7.0 and Python 2.7.10 in a virtual environment on OSX.
cURL
cURL call to the same URL on the same machine works fine:
$ curl -I https://service.isracard.co.il/I_logon.jsp
HTTP/1.1 200 OK
Date: Fri, 18 Sep 2015 11:37:27 GMT
Server: IBM_HTTP_Server
X-Powered-By: Servlet/3.0
Set-Cookie: JSESSIONID=0000R90MxFKBVxBMV665syGfjnh:-1; Path=/; HttpOnly
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Cache-Control: no-cache="set-cookie, set-cookie2"
Set-Cookie: Alt50_ZLinuxPrd=94742720.30755.0000; expires=Fri, 18-Sep-2015 12:07:19 GMT; path=/
Content-Type: text/html; charset=ISO-8859-8
Content-Language: iw-IL
Set-Cookie: ServiceP=53323968.20480.0000; path=/
Certificate validation did not fail, so the verify
argument doesn't apply here. What failed is the cipher negotiation; none of the ciphers requests
is willing to use match those the server is willing to use.
If you run your curl
command with the -v
switch you'll see what cipher suite was negotiated by curl
for the successful connection:
$ curl -v -I https://service.isracard.co.il/I_logon.jsp
* Hostname was NOT found in DNS cache
* Trying 192.118.12.8...
* Connected to service.isracard.co.il (192.118.12.8) port 443 (#0)
* TLS 1.2 connection using TLS_RSA_WITH_RC4_128_SHA
[ .... ]
That's the RC4-SHA cipher, which has some rather troublesome securty issues and should not really be used; it offers no forward secrecy for example. The urllib3
package (bundled with requests
) by default excludes that cipher from the default ciphers. You can add it back with:
import requests
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':RC4-SHA'
try:
requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST += ':RC4-SHA'
except AttributeError:
# no pyopenssl support used / needed / available
pass
and your request works:
>>> import requests
>>> requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':RC4-SHA'
>>> requests.get('https://service.isracard.co.il/I_logon.jsp')
<Response [200]>
I didn't install the pyOpenSSL package so I didn't bother with the try..except
guarded part.
这篇关于为什么 Python 请求会忽略 verify 参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!