创建Python脚本ssl.py后出现文件错误及SSL握手异常,求排查方案
先把你的报错回溯贴出来方便参考:
Traceback (most recent call last):
File "ssl-common.py", line 14, in
s = ctx.wrap_socket(s, server_hostname=dst[0])
File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 363, in wrap_socket
_context=self)
File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 611, in init
self.do_handshake()
File "/usr/local/Cellar/python/2.7/lib/python2.7/ssl.py", ...
这个错误大概率是Python2.7的ssl模块兼容性或者TLS版本支持问题导致的,下面给你几个可行的解决方向:
1. 强制使用现代TLS版本
Python2.7.13默认启用的TLS版本比较老旧(比如TLS1.0/1.1),而现在多数服务器已经禁用了这些不安全的协议版本。你可以在创建SSL上下文时指定使用TLS1.2:
import ssl import socket dst = ('目标域名', 443) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(dst) # 明确指定TLS 1.2协议 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) s = ctx.wrap_socket(s, server_hostname=dst[0])
2. 排查server_hostname参数兼容性
在部分Python2.7的ssl版本中,server_hostname参数(用于SNI扩展)的支持可能不完善。你可以尝试两种调整方式:
- 显式加载系统默认CA证书:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) ctx.set_default_verify_paths() # 加载系统CA证书 s = ctx.wrap_socket(s, server_hostname=dst[0])
- 直接使用
ssl.wrap_socket的简化写法:
s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1_2, server_hostname=dst[0])
3. 临时绕过证书验证(仅测试用)
如果是服务器证书无法被Python2.7的CA库识别导致的握手失败,你可以临时关闭证书验证(注意:生产环境绝对不能这么做,会有安全风险):
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE s = ctx.wrap_socket(s, server_hostname=dst[0])
4. 升级到Python3.x(最稳妥的长期方案)
Python2.7早在2020年就停止了官方维护,不仅ssl模块存在大量安全漏洞,对现代TLS协议的支持也严重不足。如果条件允许,直接升级到Python3.7及以上版本,新版本的ssl模块原生支持TLS1.2/1.3,API设计更合理,能从根源上避免这类兼容性问题。
内容的提问来源于stack exchange,提问作者Me Myself

