ssl 如何使用python检索CN支持的TLS版本和密码

iqjalb3h  于 2023-01-17  发布在  Python
关注(0)|答案(2)|浏览(199)

我得到的结果仅为最新支持的TLS版本(TLS 1.3),我想打印所有支持的TLS版本,如TLS 1.2、TLS 1.1等

from urllib.request import Request, urlopen, ssl, socket
    from urllib.error import URLError, HTTPError
    import json
    #some site without http/https in the path
    base_url = 'google.com'
    port = '443'`enter code here`
    
    hostname = base_url
    context = ssl.create_default_context()
    
    with socket.create_connection((hostname, port)) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as ssock:
            print(ssock.version())
            data = json.dumps(ssock.getpeercert())
            
    
    #print (data)
ktca8awb

ktca8awb1#

TLS客户端无法向服务器查询其支持的内容。TLS客户端只能提供有关密码、TLS版本、曲线等的信息,然后尝试使用此信息与服务器进行SSL握手。如果成功,则服务器支持此特定组合。
但是这也意味着TLS客户端必须首先支持这种特定的组合,例如如果服务器仍然支持RC 4密码(不安全)但是客户端TLS栈不支持它,那么SSL握手也将失败-如果TLS栈首先允许以不支持的密码开始握手。大多数现代TLS堆栈实际上禁用了这种不安全的密码,或者它们甚至经常不再编译,这意味着需要使用自己的TLS库,这些库编译为支持旧密码和TLS版本。
因此,您可以迭代所有TLS版本,并使用此特定TLS版本创建一个新上下文-请参阅ssl.SSLContext,它具有一个protocol参数。
然后你还需要在这个上下文中设置你想要用set_ciphers测试的特定密码。关于这些密码的名称和如何指定它们,请参见openssl ciphers,你也可以运行openssl ciphers -V来检查哪些密码编译到了你的特定版本的openssl中。还需要注意的是,不是所有的密码都可以与所有的TLS协议版本组合,但这也是有文档记录的。
如果TLS握手成功,你至少知道这个特定的组合是受支持的。如果它失败了,这并不意味着它在所有情况下都不受支持,因为也可能有握手问题,由于弱DH密钥,不受支持的曲线,服务器需要客户端证书等...也就是说,你的任务远非微不足道。

ulmd4ohb

ulmd4ohb2#

我有同样的问题,这就是我如何解决的。
首先获取支持的密码。您需要安装openssl

def load_ciphers(self):
    try:
        output = subprocess.run(["openssl", "ciphers"], capture_output=True).stdout
        output_str = output.decode("utf-8")
        ciphers = output_str.strip().split("\n")
        return ciphers[0]
    except:
        return ""

并使用以下命令设置密码

ciphers = load_ciphers()
    context = ssl.create_default_context()
    context.minimum_version = ssl.TLSVersion.TLSv1_2
    context.set_ciphers(ciphers)

对我很有效希望这个能帮上忙。

相关问题