我不确定是否或如何使用 Python3 请求设置 TLS 扩展。
以下代码创建一个用于 Python 3 请求的 TLS 适配器。 可以为初始 client-hello 数据包显式声明允许的密码。 但是,客户端问候数据包可以包含许多其他扩展(请参阅下面的代码中的 TLS 扩展列表)。 我尝试在 **kwargs 和 ssl_context 中指定这些,但没有成功。
请求 TLS 适配器的文档未提供允许的选项列表。 因此,我查看了HTTPAdapter的源代码,但找不到任何设置扩展的功能。 使用请求设置 TLS 扩展的最佳方法是什么?
import ssl
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
from requests.packages.urllib3.util import ssl_
CIPHERS = (
'ECDHE-RSA-AES256-GCM-SHA384:'
'ECDHE-ECDSA-AES256-GCM-SHA384:'
'ECDHE-RSA-AES256-SHA384:'
'ECDHE-ECDSA-AES256-SHA384:'
'ECDHE-RSA-AES128-GCM-SHA256:'
'ECDHE-RSA-AES128-SHA256:'
'AES256-SHA'
)
class TlsAdapter(HTTPAdapter):
def __init__(self, ssl_options=0, **kwargs):
self.ssl_options = ssl_options
super(TlsAdapter, self).__init__(**kwargs)
def init_poolmanager(self, *pool_args, **pool_kwargs):
ctx = ssl_.create_urllib3_context(ciphers=CIPHERS, cert_reqs=ssl.CERT_REQUIRED, options=self.ssl_options)
self.poolmanager = PoolManager(*pool_args,
ssl_context=ctx,
**pool_kwargs)
s = requests.session()
# Specifies no TLS 1.0 or TLS 1.1
adapter = TlsAdapter(ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1)
s.mount("https://", adapter)
s.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'}
try:
r = s.request('GET', 'https://google.com')
print(r)
except Exception as e:
print(e)
TLS 扩展列表:
Extension Name | Extension Hex Code
max_fragment_length | 0001
status_request | 0005
client_authz | 0007
server_authz | 0008
cert_type | 0009
supported_groups | 000a
ec_point_formats | 000b
signature_algorithms | 000d
heartbeat | 000f
application_layer_
protocol_negotiation | 0010
status_request_v2 | 0011
client_certificate_type| 0013
server_certificate_type| 0014
token_binding | 0018
compress_certificate | 001b
record_size_limit | 001c
supported_versions | 002b
psk_key_exchange_modes | 002d
signature_algorithms_cert| 0032
channel_id | 5500
我建议像这样设置 SSL 上下文。另请确保使用 & 运算符而不是 |操作员!
from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager
import ssl
class TlsAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False):
ctx = ssl.create_default_context()
ctx.minimum_version = ssl.TLSVersion.TLSv1_2
ctx.maximum_version = ssl.TLSVersion.TLSv1_3
ctx.options = ssl.PROTOCOL_TLS & ssl.OP_NO_TLSv1 & ssl.OP_NO_TLSv1_1
self.poolmanager = PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
ssl_context=ctx)