Python 2.7.14调用Upwork API遇TLS协议版本错误求助
解决Python 2.7.14 + OpenSSL 1.0.2k访问Upwork API的SSL连接问题
最近我踩了个坑——用Python 2.7.14搭配OpenSSL 1.0.2k(2017年1月26日版本)访问Upwork API时,遇到了SSL连接错误,试了各种协议和配置都没搞定,来跟大家说说情况和可能的解决思路:
环境与尝试的代码
- 运行环境:Python 2.7.14,OpenSSL 1.0.2k(2017-01-26发布)
- 测试代码:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS) # 所有协议都试过一遍,没用 ctx.check_hostname = False # 加不加这两行都会失败 ctx.verify_mode = ssl.CERT_NONE resp = urllib2.urlopen(url, context=ctx).read()
- 请求的URL格式(敏感信息已替换):
https://www.upwork.com/api/hr/v2/teams/../users.json?oauth_consumer_key=..&oauth_nonce=..&oauth_signature_method=HMAC-SHA1&oauth_timestamp=...
可能的解决方向
1. 明确指定TLS 1.2协议
Upwork的服务器现在大概率只支持TLS 1.2及以上版本,而PROTOCOL_TLS在旧版本里可能没有默认启用TLS 1.2,试试直接指定:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE resp = urllib2.urlopen(url, context=ctx).read()
Python 2.7.14的ssl模块已经支持PROTOCOL_TLSv1_2,而且你的OpenSSL 1.0.2k也兼容这个版本。
2. 更新CA根证书
旧版本的OpenSSL自带的根证书可能已经过期,即使你关闭了证书验证(CERT_NONE),有些服务器还是会因为证书链不完整拒绝连接。可以手动加载最新的CA证书包:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) ctx.verify_mode = ssl.CERT_REQUIRED # 替换成你下载的最新CA证书文件路径,比如从Mozilla证书库获取的ca-bundle.crt ctx.load_verify_locations('/path/to/ca-bundle.crt') resp = urllib2.urlopen(url, context=ctx).read()
3. 手动开启SNI支持
Python 2.7.14的urllib2默认可能没开启SNI(服务器名称指示),而很多现代HTTPS服务器依赖SNI才能正确返回证书。可以自定义一个HTTPS处理器来开启:
import ssl import urllib2 class SNIHTTPSHandler(urllib2.HTTPSHandler): def https_open(self, req): return self.do_open(self._get_ssl_socket, req) def _get_ssl_socket(self, host, timeout=300): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE return ssl.SSLSocket(host=host, timeout=timeout, ssl_context=ctx) # 构建自定义opener并发起请求 opener = urllib2.build_opener(SNIHTTPSHandler()) resp = opener.open(url).read()
4. 彻底升级环境(最推荐)
实话实说,Python 2.7已经停止维护好几年了,OpenSSL 1.0.2k也早就过了支持期,不仅有安全隐患,兼容性问题只会越来越多。如果条件允许,直接升级到Python 3.x(比如3.8+)搭配最新的OpenSSL版本,这些问题大概率会自动消失。
内容的提问来源于stack exchange,提问作者emanuel cristian Mocean
相关产品推荐
相关产品推荐

