为什么 Python 请求会忽略 verify 参数? [英] Why does Python requests ignore the verify parameter?

查看:32
本文介绍了为什么 Python 请求会忽略 verify 参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

我一直在尝试使用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:

https://service.isracard.co.il/I_logon.jsp

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:

Requests can also ignore verifying the SSL certificate if you set verify to False

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 参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆