Python SSL 验证备用域

Python SSL Verify Alternative Domain

我打算通过 TLS 连接到远程主机 example.com,但我必须通过具有 DNS 名称示例-proxy.com.

的代理 IP 地址进行连接

我无法控制 SSL 证书,我无法要求 example.com 的管理员将 example-proxy.com 添加到其证书的 SAN。

使用 example-prxoy.com 会导致 OpenSSL to error out 因为主机名与证书中的名称不匹配。如何将主机参数拆分为两个:(1) 用于网络连接的域名和 (2) 用于证书验证的域名。

我没有修改 OpenSSL 库的资源,但我可以更改 Python 库。根据 this doc, I could have modified the match_hostname 方法实现此功能,但从 Python 3.7+ 开始不再可用。

询问

  1. 如何使用 Python 3.7+ 指定主机名和证书名称?
  2. 从安全的角度来看,我的实现怎么会出错?

只需为 TCP 连接和 TLS 握手提供不同的主机名,即在 wrap_socket 中设置 server_hostname。要为此修改 the example from the official documentation

import socket
import ssl

tls_hostname = 'www.example.com'
context = ssl.create_default_context()

with socket.create_connection(('127.0.0.1',8443)) as sock:
    with context.wrap_socket(sock, server_hostname=tls_hostname) as ssock:
        print(ssock.version())

这将连接到 ('127.0.0.1',8443),但会与 www.example.com 进行 TLS 握手。 请注意,这将为 TLS 握手中的 SNI 扩展和验证证书使用 tls_hostname。但这似乎是你根据你的问题所需要的:连接到 IP:port 但使用特定主机名进行 TLS 握手和验证。