MacOS升级到Monterey 12.0.1后,忽然发现原来工作正常的python3请求华为restconf API报错失败,提示 ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1129) ,mac自带的curl也与huawei API握手失败,提示 curl: (35) error:06FFF089:digital envelope routines:CRYPTO_internal:bad key length 。

mac平台上默认使用的是libressl而不是openssl,ssl版本信息:LibreSSL 2.8.3,curl版本信息:curl 7.77.0 (x86_64-apple-darwin21.0) libcurl/7.77.0 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.42.0。

抓包查看ssl握手过程,发现curl和python3的表现还不太一样。

MacOS升级到Monterey后python SSL握手失败问题-LMLPHP

上图是curl的握手过程,可以看到已经完成了key exchnge,但是客户端不知什么原因主动关闭了连接,之后是服务端报错。

MacOS升级到Monterey后python SSL握手失败问题-LMLPHP

 上图是python3调用http.client.HTTPSConnection库的握手交互,可以看到刚刚发出client hello,服务端就直接报错。

同样是python3,在linux上就毫无问题,mac上的python3与其他https网站握手也没问题。对比linux上和mac上握手抓包可以看到,mac发出的client hello中多出一些字段,与华为技术沟通后表示,huawei的restconf API不支持tls1.3协议,他认为这是握手失败的原因。

MacOS升级到Monterey后python SSL握手失败问题-LMLPHP

 可以看到linux上ssl虽然也支持tls1.3,但是握手过程中没有这个supported_versions的extension,尝试在python中设置禁止tls1.3,测试结果握手成功。

解决方法如下:

from ssl import _create_unverified_context
ctx = _create_unverified_context() ctx.set_ciphers('ALL') ctx.options &= ~ssl.OP_NO_SSLv3 #允许ssl3.0,默认禁止的 ctx.options |= ssl.OP_NO_TLSv1_3 #禁止tls1.3,默认允许 opener = HTTPSConnection('xx.xx.xx.xx', port=443, timeout=3, context=ctx)
11-11 02:05