当使用Python中的requests库或其他HTTP库时,如果遇到SSL协议的问题,会导致程序抛出报错,例如[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE]。此时,我们需要检查SSL协议是否有问题,并采取一些措施来修复这个问题。
以下是完整攻略:
1. 确定问题来源
在开始解决问题之前,我们需要确定是否是SSL协议的问题导致了程序报错。为了检查SSL协议是否正常工作,我们可以使用 OpenSSL 工具来测试。
可以使用以下命令测试SSL协议是否工作正常:
openssl s_client -connect url:port
如果我们得到以下输出,则证明SSL协议存在问题:
CONNECTED(00000003)
140735717325616:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:769:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 289 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
2. 确认SSL协议版本
如果我们发现 SSL 协议确实是导致程序报错的原因,那么我们需要确认 SSL 协议版本是否支持。目前,Python requests 库默认使用的是 TLS(Transport Layer Security)协议,不再支持老旧的 SSLv3 协议。
可以使用以下方法查看requests库所使用的 SSL 协议版本:
import requests
print(requests.certs.where()) # SSL证书目录
print(requests.utils.DEFAULT_CA_BUNDLE_PATH) # SSL 证书文件
print(requests.utils.HAS_SNI) # 是否支持SNI
print(requests.utils.get_encodings_from_content(content)) # 解析content的编码
print(requests.utils.get_unicode_from_response(response)) # 解析response的编码
对于旧版requests库,可以使用以下代码获取使用的 SSL 协议版本:
print(requests.get('https://www.howsmyssl.com/a/check',verify=False).json()['tls_version'])
3. 更新 SSL 协议
如果我们需要使用 SSLv3 协议,则需要将 requests 库的默认 SSL 版本设置为 SSLv3。这可以通过以下代码实现:
import requests
import ssl
# 禁用所有SSL/TLS协议的证书验证
ssl._create_default_https_context = ssl._create_unverified_context
# requests库使用ssl3.0协议
requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST = 'TLSv1'
response = requests.get('https://')
4. 更新 requests 库
我们可以尝试更新 requests 库来解决问题,因为新版requests库在许多方面都得到了改进和更新,包括SSL协议和TLS协议的支持。
可以使用以下命令更新requests库:
pip install requests --upgrade
5. 略过 SSL 验证
在某些情况下,我们可以选择简单地略过 SSL 验证,直接请求数据。虽然这是一个比较危险的做法,但对于某些测试任务来说,可能是一个可行的解决方案。
可以使用以下代码略过 SSL 验证:
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
response = requests.get('https://',verify=False)
上述代码使用 verify=False 参数,禁用 SSL 验证。需要注意的是,这个方法仍然会产生警告,我们可以使用 requests.packages.urllib3.disable_warnings 函数来关闭这个警告。
示例说明
示例 1
如果我们使用了 requests 库,而且我们在使用 SSL 或 TLS 连接时遇到了 SSLv3 报错,那么可以使用以下代码来解决这个问题:
# 加载requests库
import requests
import ssl
# 禁用所有SSL/TLS协议的证书验证
ssl._create_default_https_context = ssl._create_unverified_context
# requests库使用ssl3.0协议
requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST = 'TLSv1'
response = requests.get('https://')
上述代码中,我们使用 ssl._create_unverified_context 来创建一个未经验证的SSL/TLS上下文,然后将其设置为当前默认上下文。
示例 2
如果我们需要使用更老旧的 SSLv2 协议,那么可以使用以下代码:
import requests
import ssl
# 禁用所有SSL/TLS协议的证书验证
ssl._create_default_https_context = ssl._create_unverified_context
# requests库使用ssl2.0协议
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL'
requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST = 'SSLv2'
response = requests.get('https://',verify=False)
上述代码中,我们使用 requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS 来设置所有密码套件,然后将 requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST 设置为 SSLv2。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:解决Python报错问题[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] - Python技术站