Python SSL错误握手 [英] Python SSL Bad Handshake

查看:197
本文介绍了Python SSL错误握手的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个非常特殊的问题。
特别是,我想检索以下网站的内容: https://www.mycardtamoil.it/



据我了解,该网站的SSL证书存在一些问题。如果您在Chrome中打开它,就没有问题,但是如果您尝试通过cURL( curl https://www.mycardtamoil.it/ )检索内容,则会收到可以使用 -k



选项绕过的ssl错误,当我使用Python3时,我不是能够绕过这个问题;我测试过的代码是:

 导入请求
response = requests.get('https:// www .mycardtamoil.it /',verify = False)

但我得到以下期望:


------------------------------- -------------------------------------------- SysCallError Traceback(最近的呼叫
最后)
C:\ProgramData\Anaconda3\lib\site-packages\urllib3\contrib\pyopenssl.py
在wrap_socket(self,sock,server_side, do_handshake_on_connect,
inhibitor_ragged_eofs,server_hostname)
440尝试:
-> 441 cnx.do_handshake()
442除了OpenSSL.SSL.WantReadError:



C:\ProgramData\Anaconda3\lib\站点软件包\OpenSSL\SSL.py in
do_handshake(self)1906结果=
_lib.SSL_do_handshake (self._ssl)
-> 1907 self._raise_ssl_error(self._ssl,结果) 1908



C:\ProgramData\Anaconda3\lib\site-packages\OpenSSL\SSL.py in
_raise_ssl_error(self,ssl ,结果)1631提高SysCallError(errno,errorcode.get(errno))
-> 1632提高SysCallError(-1,意外的EOF)1633否则:



SysCallError:(-1,意外的EOF)



在处理上述异常期间,发生了另一个异常:



SSLError Traceback(最近一次调用
最后)
C:\ProgramData\Anaconda3\lib\site-packages\urllib3\connectionpool.py
在urlopen中((自身,方法,URL,正文,标头,重试,重定向,
assert_same_host,超时,pool_timeout,release_conn,分块,
body_pos,** response_kw))
600 body = body,headers =标头,
-> 601 chunked = chunk ed)
602



C:\ProgramData\Anaconda3\lib\site-packages\urllib3\connectionpool.py
在_make_request中(self,conn,method,url,timeout,chunked,
** httplib_request_kw)
345试试:
-> 346 self._validate_conn(conn)
347除了(SocketTimeout,BaseSSLError)为e:



C:\ProgramData\Anaconda3\lib\site-packages\urllib3\connectionpool.py $ b $ _validate_conn(self,conn)
中的b如果没有getattr(conn,'sock',None)则为849:#AppEngine可能没有 .sock
-> 850 conn.connect()
851



C:\ProgramData\Anaconda3\lib\site-packages\urllib3\
中的connection.py connect(self)
325 server_hostname = hostname,
-> 326 ssl_context = context)
327



C:\ProgramData\Anaconda3\lib\站点包\urllib3\util\ssl_.py in
ssl_ wrap_socket(sock,keyfile,certfile,cert_reqs,ca_certs,
server_hostname,ssl_version,密码,ssl_context,ca_cert_dir)
328如果HAS_SNI:#特定于平台:启用了SNI的OpenSSL
-> 329 return context.wrap_socket(sock,server_hostname = server_hostname)
330



C:\ProgramData\Anaconda3\lib\site-packages\ urllib3\contrib\pyopenssl.py
在wrap_socket中(self,sock,server_side,do_handshake_on_connect,
inhibitor_ragged_eofs,server_hostname)
447除了OpenSSL.SSL。错误如e:
-> 448提高ssl.SSLError('握手错误:%r'%e)
449 break



SSLError:(握手错误:SysCallError(- 1,'意外的EOF')))



在处理上述异常期间,发生了另一个异常:



MaxRetryError Traceback(最近一次调用
最后)C:\ProgramData\Ana conda3\lib\site-packages\requests\adapters.py
发送(自身,请求,流,超时,验证,证书,代理)
439 retries = self.max_retries,
-> 440超时=超时
441)



C:\ProgramData\Anaconda3\lib\site-packages\urllib3 pool urlopen中的connectionpool.py
(自身,方法,URL,主体,标头,重试,重定向,
assert_same_host,超时,pool_timeout,release_conn,分块,
body_pos,** response_kw)
638重试= retries.increment(方法,URL,错误= e,_pool =自我,
-> 639 _stacktrace = sys.exc_info()[2])
640 retries.sleep ()



C:\ProgramData\Anaconda3\lib\site-packages\urllib3\util\retry.py,以
递增(self,method,url,response,error,_pool,_stacktrace)
387如果new_retry.is_exhausted():
-> 388提高MaxRetryError(_pool,url,错误或ResponseError(原因))
389



MaxRetryError:HTTPSConnectionPool(host ='www.mycardtamoil.it',
port = 443):url超过了最大重试次数:/(由
SSLError(SSLError( bad handshake:SysCallError(-1,'Unexpected
EOF'),),)导致))) / p>

在处理上述异常期间,发生了另一个异常:



SSLError Traceback(最近一次调用
last)in()
1个导入请求
----> 2个响应= requests.get(' https://www.mycardtamoil.it/ ',verify = False)



C:\ProgramData\Anaconda3\lib\ get(URL,
params,** kwargs)中的site-packages\requests\api.py
70
71 kwargs.setdefault('allow_redirects',True)
---> 72个返回请求('get',url,params = params,** kwargs)
73
74



C:\ProgramData\Anaconda3\lib\site-packages\requests\api.py in
request(method,url ,** kwargs)
56#情况,在其他情况下看起来像是内存泄漏。
57具有sessions.Session()作为会话:
---> 58 return session.request(method = method,url = url,** kwargs)
59
60



C:\ProgramData\Anaconda3\lib\site-packages\requests\sessions.py in
request(self,method,网址,参数,数据,标头,Cookie,文件,
身份验证,超时,allow_redirects,代理,挂钩,流,验证,证书,
json)
506}
507 send_kwargs .update(settings)
-> 508 resp = self.send(prep,** send_kwargs)
509
510 return resp



C:\ProgramData\Anaconda3\lib\站点包\requests\sessions.py in
send(self,request,** kwargs)
616
617#发送请求
-> 618 r = adapter.send(请求,** kwargs)
619
620#请求的总经过时间(大约)



C:\ProgramData\Anacond
中的a3\lib\site-packages\requests\adapters.py send(自身,请求,流,超时,验证,证书,代理)
504 if isinstance(e.reason, _SSLError):
505#此分支适用于urllib3 v1.22及更高版本。
-> 506引发SSLError(e,request = request)
507
508引发ConnectionError(e,request = request)



SSLError:HTTPSConnectionPool(host ='www.mycardtamoil.it',端口= 443):
网址已超过最大重试次数:/(由SSLError(SSLError(不良
握手引起:SysCallError(-1 ,意外的EOF)))))


有人可以帮助我了解如何使用请求模块进行修复吗?



在此先感谢
Salvo

解决方案

根据服务器 SSLLabs 的设置很糟糕。值得注意的是,它仅支持TLS 1.0及以下版本(甚至或多或少地破坏了SSLv3和绝对被破坏的SSLv2),并且还仅支持被认为是弱的或确实不安全的密码。



虽然客户端通常支持TLS 1.0(尽管存在已知问题,但仍被认为足够安全),但它们通常不支持弱密码和不安全密码-至少在默认情况下,但有时不支持甚至不再编译。服务器支持的不那么安全的密码可能是TLS_RSA_WITH_3DES_EDE_CBC_SHA(在OpenSSL中称为DES-CBC3-SHA)。



假定此密码在使用的OpenSSL版本中仍然可用通过您的Python,您可以破解请求以启用此密码。根据此问题,可以这样操作:

 导入请求
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS ='DES-CBC3-SHA'
requests.get('https://www.mycardtamoil.it/')

现在不再得到意外的EOF ,它将收到另一个错误:证书验证失败。这是因为服务器设置不仅在协议版本和密码方面被破坏,而且证书配置不正确。 SSLLabs报告在所有其他问题中也显示了


此服务器的证书链不完整。


添加 verify = False 就像通过添加来修复问题甚至更加不安全,即它会跳过证书的验证。请参见此处,了解如何解决这种情况正确固定。尽管目前尚不清楚,在这种情况下(您必须处理严重损坏且不安全的系统),正确检查证书是否会真正显着提高安全性。无论是否使用HTTPS,我都建议不要向该系统发送任何敏感数据。


I'm having a very particular problem. In particular, I'd like to retrieve the content of the following website: https://www.mycardtamoil.it/

As I understood, this website has some issues with the SSL certificate. If you open it in Chrome, you have no issue, but if you try to retrieve the content via cURL (curl https://www.mycardtamoil.it/) you receive an error on ssl that can bypass using the option -k

When I move to Python3, I'm not able to bypass this issue; the code I've tested is:

import requests
response = requests.get('https://www.mycardtamoil.it/', verify=False)

but I get the following expection:

--------------------------------------------------------------------------- SysCallError Traceback (most recent call last) C:\ProgramData\Anaconda3\lib\site-packages\urllib3\contrib\pyopenssl.py in wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname) 440 try: --> 441 cnx.do_handshake() 442 except OpenSSL.SSL.WantReadError:

C:\ProgramData\Anaconda3\lib\site-packages\OpenSSL\SSL.py in do_handshake(self) 1906 result = _lib.SSL_do_handshake(self._ssl) -> 1907 self._raise_ssl_error(self._ssl, result) 1908

C:\ProgramData\Anaconda3\lib\site-packages\OpenSSL\SSL.py in _raise_ssl_error(self, ssl, result) 1631 raise SysCallError(errno, errorcode.get(errno)) -> 1632 raise SysCallError(-1, "Unexpected EOF") 1633 else:

SysCallError: (-1, 'Unexpected EOF')

During handling of the above exception, another exception occurred:

SSLError Traceback (most recent call last) C:\ProgramData\Anaconda3\lib\site-packages\urllib3\connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw) 600 body=body, headers=headers, --> 601 chunked=chunked) 602

C:\ProgramData\Anaconda3\lib\site-packages\urllib3\connectionpool.py in _make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw) 345 try: --> 346 self._validate_conn(conn) 347 except (SocketTimeout, BaseSSLError) as e:

C:\ProgramData\Anaconda3\lib\site-packages\urllib3\connectionpool.py in _validate_conn(self, conn) 849 if not getattr(conn, 'sock', None): # AppEngine might not have .sock --> 850 conn.connect() 851

C:\ProgramData\Anaconda3\lib\site-packages\urllib3\connection.py in connect(self) 325 server_hostname=hostname, --> 326 ssl_context=context) 327

C:\ProgramData\Anaconda3\lib\site-packages\urllib3\util\ssl_.py in ssl_wrap_socket(sock, keyfile, certfile, cert_reqs, ca_certs, server_hostname, ssl_version, ciphers, ssl_context, ca_cert_dir) 328 if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI --> 329 return context.wrap_socket(sock, server_hostname=server_hostname) 330

C:\ProgramData\Anaconda3\lib\site-packages\urllib3\contrib\pyopenssl.py in wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname) 447 except OpenSSL.SSL.Error as e: --> 448 raise ssl.SSLError('bad handshake: %r' % e) 449 break

SSLError: ("bad handshake: SysCallError(-1, 'Unexpected EOF')",)

During handling of the above exception, another exception occurred:

MaxRetryError Traceback (most recent call last) C:\ProgramData\Anaconda3\lib\site-packages\requests\adapters.py in send(self, request, stream, timeout, verify, cert, proxies) 439 retries=self.max_retries, --> 440 timeout=timeout 441 )

C:\ProgramData\Anaconda3\lib\site-packages\urllib3\connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw) 638 retries = retries.increment(method, url, error=e, _pool=self, --> 639 _stacktrace=sys.exc_info()[2]) 640 retries.sleep()

C:\ProgramData\Anaconda3\lib\site-packages\urllib3\util\retry.py in increment(self, method, url, response, error, _pool, _stacktrace) 387 if new_retry.is_exhausted(): --> 388 raise MaxRetryError(_pool, url, error or ResponseError(cause)) 389

MaxRetryError: HTTPSConnectionPool(host='www.mycardtamoil.it', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: SysCallError(-1, 'Unexpected EOF')",),))

During handling of the above exception, another exception occurred:

SSLError Traceback (most recent call last) in () 1 import requests ----> 2 response = requests.get('https://www.mycardtamoil.it/', verify=False)

C:\ProgramData\Anaconda3\lib\site-packages\requests\api.py in get(url, params, **kwargs) 70 71 kwargs.setdefault('allow_redirects', True) ---> 72 return request('get', url, params=params, **kwargs) 73 74

C:\ProgramData\Anaconda3\lib\site-packages\requests\api.py in request(method, url, **kwargs) 56 # cases, and look like a memory leak in others. 57 with sessions.Session() as session: ---> 58 return session.request(method=method, url=url, **kwargs) 59 60

C:\ProgramData\Anaconda3\lib\site-packages\requests\sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json) 506 } 507 send_kwargs.update(settings) --> 508 resp = self.send(prep, **send_kwargs) 509 510 return resp

C:\ProgramData\Anaconda3\lib\site-packages\requests\sessions.py in send(self, request, **kwargs) 616 617 # Send the request --> 618 r = adapter.send(request, **kwargs) 619 620 # Total elapsed time of the request (approximately)

C:\ProgramData\Anaconda3\lib\site-packages\requests\adapters.py in send(self, request, stream, timeout, verify, cert, proxies) 504 if isinstance(e.reason, _SSLError): 505 # This branch is for urllib3 v1.22 and later. --> 506 raise SSLError(e, request=request) 507 508 raise ConnectionError(e, request=request)

SSLError: HTTPSConnectionPool(host='www.mycardtamoil.it', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: SysCallError(-1, 'Unexpected EOF')",),))

Can someone help me to understand how I can fix it using requests module?

Thanks in advance, Salvo

解决方案

According to SSLLabs the server has a terrible setup. Notably it only supports TLS 1.0 and less (even the more or less broken SSLv3 and the absolutely broken SSLv2) and it also only supports ciphers which are considered weak or really insecure.

While clients usually support TLS 1.0 (still considered sufficiently secure despite known problems) they usually don't support weak and insecure ciphers - at least by default but sometimes they are not even compiled in any longer. Probably the less insecure cipher supported by the server is TLS_RSA_WITH_3DES_EDE_CBC_SHA (called DES-CBC3-SHA within OpenSSL).

Assuming that this cipher is still available in the version of OpenSSL used by your Python you could hack requests into enable this cipher. Based on this question this could be done like this:

import requests
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'DES-CBC3-SHA'
requests.get('https://www.mycardtamoil.it/')

While it now no longer gets a Unexpected EOF it gets another error: certificate verify failed. This is because the servers setup is not only broken regarding protocol versions and ciphers but also the certificate is not properly configured. The SSLLabs report shows among all the other problems also

This server's certificate chain is incomplete.

Adding verify=False like you did "fixes" the problem by adding even more insecurity, i.e. it skips the validation of the certificate. See here for how such situations can be properly fixed. Although, it is not clear if properly checking the certificate would actually significantly improve the security in this situation where you have to deal with a severely broken and insecure system. I recommend to not sent any sensitive data to this system, no matter if HTTPS is used or not.

这篇关于Python SSL错误握手的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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