You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python ssl中获取自定义配置的TLS客户端支持协议版本

刚好之前研究过这个问题,Python的ssl模块确实没有像get_ciphers()那样直接返回支持协议版本的API,但我们可以通过两种方式来获取:

方法一:解析上下文的options参数

当你通过context.options排除协议版本时,本质是设置了ssl.OP_NO_*系列的常量。我们可以通过对比这些常量是否被设置,反向推导出当前上下文支持的协议版本。

示例代码:

import ssl

def get_supported_protocols(context):
    # 映射协议名称到对应的禁用选项
    protocol_option_map = {
        "SSLv2": ssl.OP_NO_SSLv2,
        "SSLv3": ssl.OP_NO_SSLv3,
        "TLSv1": ssl.OP_NO_TLSv1,
        "TLSv1.1": ssl.OP_NO_TLSv1_1,
        "TLSv1.2": ssl.OP_NO_TLSv1_2,
        "TLSv1.3": ssl.OP_NO_TLSv1_3
    }
    
    supported_protocols = []
    for proto_name, opt_flag in protocol_option_map.items():
        # 如果该禁用选项未被设置,说明支持对应协议
        if not (context.options & opt_flag):
            supported_protocols.append(proto_name)
    
    return supported_protocols

# 测试:创建上下文并排除TLSv1和TLSv1.1
ctx = ssl.create_default_context()
ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1

print("当前支持的协议版本:", get_supported_protocols(ctx))

注意事项:

  • Python的create_default_context()默认已经禁用了SSLv2和SSLv3(出于安全考虑),所以即使代码中没显式排除,这两个协议也不会出现在结果里。
  • 不同Python版本支持的协议范围可能不同,比如TLSv1.3需要Python 3.7及以上版本,且底层依赖OpenSSL 1.1.1+。

方法二:通过实际握手测试验证

如果想要更准确的结果(比如考虑底层OpenSSL库的限制),可以尝试和支持多版本的服务器握手,逐个验证协议是否可用。

示例代码:

import ssl
import socket

def is_protocol_supported(target_protocol):
    # 创建仅允许目标协议的上下文
    ctx = ssl.create_default_context()
    # 禁用所有其他协议
    if target_protocol == "TLSv1":
        ctx.options |= ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2 | ssl.OP_NO_TLSv1_3 | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3
    elif target_protocol == "TLSv1.1":
        ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_2 | ssl.OP_NO_TLSv1_3 | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3
    elif target_protocol == "TLSv1.2":
        ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_3 | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3
    elif target_protocol == "TLSv1.3":
        ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2 | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3
    
    try:
        # 连接到Cloudflare的公共DNS服务器(支持多种TLS版本)
        with socket.create_connection(("1.1.1.1", 443)) as sock:
            with ctx.wrap_socket(sock, server_hostname="1.1.1.1") as ssl_sock:
                return True, ssl_sock.version()
    except ssl.SSLError:
        return False, None

# 检测所有常见协议版本
test_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"]
supported = []
for proto in test_protocols:
    success, actual_version = is_protocol_supported(proto)
    if success:
        supported.append(actual_version)

print("实际支持的协议版本:", supported)

优缺点:

  • 优点:能真实反映系统实际支持的协议(比如如果底层OpenSSL不支持TLSv1.3,即使Python配置允许,也会被检测出来)。
  • 缺点:需要网络连接,且依赖测试服务器对对应协议的支持。

内容的提问来源于stack exchange,提问作者user9371654

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:57:54