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

如何自定义SSL握手流程?排查HTTPS服务器握手失败问题

Debugging Handshake Failures by Customizing SSL Handshakes in Python

First off, that handshake_failure error right after ClientHello is super frustrating—especially when browsers work fine. The key here is to mirror what your browser is sending because that weird server is almost certainly rejecting your Python client for missing or mismatching SSL parameters. Let’s break down how to customize the handshake step by step.

Step 1: Compare Browser vs. Requests ClientHello

First, use Wireshark to capture the ClientHello packet from your working browser, then capture the one from Requests. Look for these critical differences:

  • Cipher Suites: The order and list of ciphers your browser uses (servers often prioritize certain ciphers)
  • SSL/TLS Version: Browsers typically use TLS 1.2+; maybe Requests is defaulting to an older version the server rejects
  • Extensions: Things like ALPN (HTTP/2 support), SNI (server name indication—critical for virtual hosts), EC point formats, session tickets, or even custom extensions the server expects
  • Compression: Some servers care about whether compression is enabled/disabled

Step 2: Customize SSLContext for Requests

Requests uses Python’s ssl module under the hood, so you can create a custom SSLContext to match your browser’s settings. Here’s a code example to get you started:

import requests
import ssl

# Create a custom SSL context starting with defaults
ctx = ssl.create_default_context()

# 1. Match your browser's cipher suite list (replace with your Wireshark capture)
# Use the exact string from your browser's ClientHello "Cipher Suites" field
ctx.set_ciphers(
    "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:"
    "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:"
    "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:"
    "DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
)

# 2. Enable ALPN protocols (match browser's supported protocols, e.g., h2 + http/1.1)
ctx.set_alpn_protocols(['h2', 'http/1.1'])

# 3. Set ECDH curve to match browser (common ones: prime256v1, secp384r1)
ctx.set_ecdh_curve('prime256v1')

# 4. Disable older, unsupported TLS versions (match browser's enabled versions)
ctx.options |= ssl.OP_NO_SSLv3
ctx.options |= ssl.OP_NO_TLSv1
ctx.options |= ssl.OP_NO_TLSv1_1

# 5. Optional: Add browser's User-Agent (some servers check this too)
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'}

# Send request with custom context and headers
try:
    response = requests.get("https://your-weird-server.com", headers=headers, ssl_context=ctx, verify=False)
    print(f"Success! Status code: {response.status_code}")
except requests.exceptions.SSLError as e:
    print(f"SSL Error: {e}")

Step 3: Debugging Custom Extensions

If the server expects a rare or custom extension that Python’s ssl module doesn’t support by default, you’ll need to use a more flexible library like pyOpenSSL. With pyOpenSSL, you can manually add extensions to the ClientHello.

Here’s a quick snippet to add a custom extension (adjust the OID and data to match what you see in the browser’s capture):

from OpenSSL import SSL
import requests
from urllib3.contrib.pyopenssl import PyOpenSSLContext

# Create a PyOpenSSL context
ctx = PyOpenSSLContext(SSL.TLSv1_2_METHOD)

# Add a custom extension (example: OID 1.2.3.4 with empty data)
# Replace with the extension bytes (OID + length + data) from your browser's capture
ctx._ctx.add_client_custom_ext(
    b"\x00\x12\x04\x00\x00",  # Example extension bytes
    lambda *_: None
)

# Use this context with Requests
response = requests.get("https://your-weird-server.com", ssl_context=ctx, verify=False)

Step 4: Iterate and Test

After each change, use Wireshark to capture the new ClientHello and compare it to the browser’s. Adjust one parameter at a time (e.g., first fix ciphers, then ALPN) to isolate exactly which setting the server is rejecting.

If you’re still stuck, tools like sslyze can scan the server to list supported ciphers, protocols, and extensions—this can help you cross-reference your client’s settings.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:34:27