使用 IronPython 强制 SSL 协议 TLSv1.2
Force SSL Protocol TLSv1.2 with IronPython
我正在 Python 中开发一个 API 包装器,它适用于 CPython 2.7 和 3。
当我从 IronPython 访问 https 服务器时,我得到了下面的回溯
IOError: System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
我分析了不同平台发送的包,发现唯一的区别是 IronPython 是唯一使用 TSL 1.0 协议的包,而 CPython 使用 TSL 1.2(见截图下面)
我使用下面的代码强制 Cpython 使用 TSL 1.0 并得到了完全相同的错误,这证实了问题出在 TSL 协议上。
(代码允许我一致地更改 HTTP 适配器协议)
我遇到的问题是,下面的代码似乎对 IronPython 没有影响,并且无论如何它都会继续对所有请求使用 TSL 1.0。
有什么想法吗?这可能是 IronPython 错误吗?
import sys
import platform
print(platform.python_implementation())
print(sys.version_info[0:2])
import ssl
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
if platform.python_implementation() == 'IronPython':
print('Setting TSL Protocol')
import System
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12
class ForceTLSV12Adapter(HTTPAdapter):
"""Require TLSv1 for the connection"""
def init_poolmanager(self, connections, maxsize, block=False):
# This method gets called when there's no proxy.
self.poolmanager = PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
ssl_version=ssl.PROTOCOL_TLSv1_2,
# ssl_version=ssl.PROTOCOL_TLSv1,
)
def proxy_manager_for(self, proxy, **proxy_kwargs):
# This method is called when there is a proxy.
proxy_kwargs['ssl_version'] = ssl.PROTOCOL_TLSv1_2
return super(ForceTLSV1Adapter, self).proxy_manager_for(proxy, **proxy_kwargs)
s = requests.Session()
s.mount('https://api.unleashedsoftware.com', ForceTLSV12Adapter())
print(s.get("https://api.unleashedsoftware.com"))
PS:我也试过设置系统范围的默认协议,但似乎没有任何效果:
https://support.microsoft.com/en-us/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-a-default-secure-protocols-in
代码运行正常。问题是 IronPython 中的错误:
https://github.com/IronLanguages/ironpython2/issues/227
我正在 Python 中开发一个 API 包装器,它适用于 CPython 2.7 和 3。
当我从 IronPython 访问 https 服务器时,我得到了下面的回溯
IOError: System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
我分析了不同平台发送的包,发现唯一的区别是 IronPython 是唯一使用 TSL 1.0 协议的包,而 CPython 使用 TSL 1.2(见截图下面)
我使用下面的代码强制 Cpython 使用 TSL 1.0 并得到了完全相同的错误,这证实了问题出在 TSL 协议上。 (代码允许我一致地更改 HTTP 适配器协议)
我遇到的问题是,下面的代码似乎对 IronPython 没有影响,并且无论如何它都会继续对所有请求使用 TSL 1.0。
有什么想法吗?这可能是 IronPython 错误吗?
import sys
import platform
print(platform.python_implementation())
print(sys.version_info[0:2])
import ssl
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
if platform.python_implementation() == 'IronPython':
print('Setting TSL Protocol')
import System
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12
class ForceTLSV12Adapter(HTTPAdapter):
"""Require TLSv1 for the connection"""
def init_poolmanager(self, connections, maxsize, block=False):
# This method gets called when there's no proxy.
self.poolmanager = PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
ssl_version=ssl.PROTOCOL_TLSv1_2,
# ssl_version=ssl.PROTOCOL_TLSv1,
)
def proxy_manager_for(self, proxy, **proxy_kwargs):
# This method is called when there is a proxy.
proxy_kwargs['ssl_version'] = ssl.PROTOCOL_TLSv1_2
return super(ForceTLSV1Adapter, self).proxy_manager_for(proxy, **proxy_kwargs)
s = requests.Session()
s.mount('https://api.unleashedsoftware.com', ForceTLSV12Adapter())
print(s.get("https://api.unleashedsoftware.com"))
PS:我也试过设置系统范围的默认协议,但似乎没有任何效果: https://support.microsoft.com/en-us/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-a-default-secure-protocols-in
代码运行正常。问题是 IronPython 中的错误: https://github.com/IronLanguages/ironpython2/issues/227