【问题标题】:How to select specific the cipher while sending request via python request module如何在通过 python 请求模块发送请求时选择特定的密码
【发布时间】:2017-03-15 08:41:34
【问题描述】:

用例:我想通过 python 请求模块找出主机名支持多少密码。

我无法找到一种方法来提供密码名称来请求模块挂钩。任何人都可以建议提供指定密码的方式。

import ssl

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager


class Ssl3HttpAdapter(HTTPAdapter):
    """"Transport adapter" that allows us to use SSLv3."""

    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(
            num_pools=connections, maxsize=maxsize,
            block=block, ssl_version=ssl.PROTOCOL_SSLv3)

【问题讨论】:

    标签: python python-3.x https python-requests pyopenssl


    【解决方案1】:

    如果您使用请求版本 2.12.0+,Configuring TLS With Requests 上有一篇博文,其中描述了允许您配置 SSLContext 的新功能(请注意,这篇博文是在 OP 提出问题后编写的) :

    Requests v2.12.0 中添加的功能是 urllib3 现在接受一个 ConnectionPool 对象的构造函数中的 SSLContext 对象。这 SSLContext 将用作底层 TLS 的工厂 连接,因此应用于它的所有设置也将应用于 那些低级的连接。

    最好的方法是使用 SSLContext 工厂函数 requests.packages.urllib3.util.ssl_.create_urllib3_context。这是 类似于 Python 的 ssl.create_default_context 函数,但适用 Requests 和 urllib3 的更严格的默认 TLS 配置 两者都使用。这个函数将返回一个 SSLContext 对象,然后可以 应用了进一步的配置。最重要的是,该功能还 需要一些参数来允许覆盖默认配置。

    要提供新的 SSLContext 对象,您需要编写一个 适用于给定主机的 TransportAdapter。

    以下示例代码作为示例,说明如何使用此方法在请求中重新启用 3DES。

    import requests
    from requests.adapters import HTTPAdapter
    from requests.packages.urllib3.util.ssl_ import create_urllib3_context
    
    # This is the 2.11 Requests cipher string, containing 3DES.
    CIPHERS = (
        'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
        'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
        '!eNULL:!MD5'
    )
    
    
    class DESAdapter(HTTPAdapter):
        """
        A TransportAdapter that re-enables 3DES support in Requests.
        """
        def init_poolmanager(self, *args, **kwargs):
            context = create_urllib3_context(ciphers=CIPHERS)
            kwargs['ssl_context'] = context
            return super(DESAdapter, self).init_poolmanager(*args, **kwargs)
    
        def proxy_manager_for(self, *args, **kwargs):
            context = create_urllib3_context(ciphers=CIPHERS)
            kwargs['ssl_context'] = context
            return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)
    
    s = requests.Session()
    s.mount('https://some-3des-only-host.com', DESAdapter())
    r = s.get('https://some-3des-only-host.com/some-path')
    

    还有一个 hack 可能,您可以在 github pages for the requests modulehttps://stackoverflow.com/a/32651967/2364215 上阅读它,但它会修改底层库代码,我不推荐它(请求模块的作者也不推荐,因为您将在该页面上找到)。另一方面,如果您使用的是较旧的请求包并且无法升级,那么它可能是您的最佳选择。相当于覆盖了 urllib3 模块的DEFAULT_CIPHERS:

    requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':RC4-SHA' 
    

    如果您有其他代码在修改后将使用 requests 模块,但不需要修改,您可能需要将 DEFAULT_CIPHERS 恢复为之前的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      相关资源
      最近更新 更多