【问题标题】:How to force python use TLS1.2, not TLS1.3如何强制 python 使用 TLS1.2,而不是 TLS1.3
【发布时间】:2023-02-19 17:15:37
【问题描述】:

我需要强制 python 发出最大 TLS 版本设置为 1.2 而不是 1.3 的 https 请求,但我做不到。

我通过这个 json 检查客户端公布了哪些参数 - https://www.howsmyssl.com/a/check

平台:Win10

尝试了几件事,例如:

class TLSv1_2HttpAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        ssl_context = ssl.create_default_context()
        ssl_context.minimum_version = ssl.TLSVersion.TLSv1
        ssl_context.maximum_version = ssl.TLSVersion.TLSv1_2
        ssl_context.options = ssl.PROTOCOL_TLS | ssl.OP_NO_TLSv1_3
        
        self.poolmanager = PoolManager(
            num_pools=connections,
            maxsize=maxsize,
            block=block,
            ssl_version=ssl.PROTOCOL_TLS | ssl.OP_NO_TLSv1_3,
            ssl_context=ssl_context)

或者

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.Context(SSL.TLSv1_2_METHOD)
        self.poolmanager = PoolManager(*pool_args,
                                        ssl_context=ctx,
                                        **pool_kwargs)

...它不起作用 - 它仍然使用 TLS1.3 忽略我的设置。 我像这样使用它:

s = requests.Session()
s.mount('https://', TlsAdapter())
req = requests.Request('GET','https://www.howsmyssl.com/a/check')
prepped = req.prepare()
r = s.send(prepped,
    verify=False,
    proxies=proxies,
    allow_redirects=False
)
print(ssl.OPENSSL_VERSION)
print(r.json())

它给了我以下凭据:

OpenSSL 1.1.1k  25 Mar 2021
{'given_cipher_suites': ['TLS_AES_256_GCM_SHA384', 'TLS_CHACHA20_POLY1305_SHA256', 'TLS_AES_128_GCM_SHA256', 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384', 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384', 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256', 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256', 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256', 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256', 'TLS_DHE_RSA_WITH_AES_256_GCM_SHA384', 'TLS_DHE_RSA_WITH_AES_128_GCM_SHA256', 'TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256', 'TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8', 'TLS_ECDHE_ECDSA_WITH_AES_256_CCM', 'TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8', 'TLS_ECDHE_ECDSA_WITH_AES_128_CCM', 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384', 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384', 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256', 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256', 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA', 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA', 'TLS_DHE_RSA_WITH_AES_256_CCM_8', 'TLS_DHE_RSA_WITH_AES_256_CCM', 'TLS_DHE_RSA_WITH_AES_128_CCM_8', 'TLS_DHE_RSA_WITH_AES_128_CCM', 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA256', 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA256', 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA', 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA', 'TLS_RSA_WITH_AES_256_GCM_SHA384', 'TLS_RSA_WITH_AES_128_GCM_SHA256', 'TLS_RSA_WITH_AES_256_CCM_8', 'TLS_RSA_WITH_AES_256_CCM', 'TLS_RSA_WITH_AES_128_CCM_8', 'TLS_RSA_WITH_AES_128_CCM', 'TLS_RSA_WITH_AES_256_CBC_SHA256', 'TLS_RSA_WITH_AES_128_CBC_SHA256', 'TLS_RSA_WITH_AES_256_CBC_SHA', 'TLS_RSA_WITH_AES_128_CBC_SHA', 'TLS_EMPTY_RENEGOTIATION_INFO_SCSV'],
'ephemeral_keys_supported': True,
'session_ticket_supported': True,
'tls_compression_supported': False,
'unknown_cipher_suite_supported': False,
'beast_vuln': False,
'able_to_detect_n_minus_one_splitting': False,
'insecure_cipher_suites': {},
'tls_version': 'TLS 1.3',
'rating': 'Probably Okay'}

我究竟做错了什么?

【问题讨论】:

    标签: python python-3.x ssl openssl tls1.2


    【解决方案1】:

    尝试将 PoolManager 类中的 ssl_version 参数设置为 ssl.PROTOCOL_TLSv1_2 而不是 ssl.PROTOCOL_TLS | ssl.OP_NO_TLSv1_3。

    这是一个更新的示例:

    class TLSv1_2HttpAdapter(HTTPAdapter):
        def init_poolmanager(self, *args, **kwargs):
            ctx = ssl.create_default_context()
            ctx.minimum_version = ssl.TLSVersion.TLSv1
            ctx.maximum_version = ssl.TLSVersion.TLSv1_2
            ctx.options |= ssl.OP_NO_TLSv1_3
            self.poolmanager = PoolManager(*args,
                                           ssl_version=ssl.PROTOCOL_TLSv1_2,
                                           ssl_context=ctx,
                                           **kwargs)
    
    s = requests.Session()
    s.mount('https://', TLSv1_2HttpAdapter())
    req = requests.Request('GET', 'https://www.howsmyssl.com/a/check')
    prepped = req.prepare()
    r = s.send(prepped,
               verify=False,
               allow_redirects=False)
    print(ssl.OPENSSL_VERSION)
    print(r.json())
    

    【讨论】:

      猜你喜欢
      • 2021-11-19
      • 2018-04-20
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      • 2014-12-22
      • 1970-01-01
      • 2017-01-02
      相关资源
      最近更新 更多