Python SSL与TLS安全连接实现细节
2026/6/16 16:48:22 网站建设 项目流程

Python SSL与TLS安全连接实现细节

ssl模块提供TLS/SSL协议的Python封装。它基于OpenSSL库,支持客户端和服务器的安全通信。

创建TLS上下文:

import ssl

# 创建客户端上下文
ctx = ssl.create_default_context()
# 自动加载系统CA证书

# 创建服务器上下文
server_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
server_ctx.load_cert_chain(certfile='server.crt', keyfile='server.key')

create_default_context根据用途预设安全选项。ssl.Purpose.SERVER_AUTH用于客户端连接,ssl.Purpose.CLIENT_AUTH用于服务器连接。

自定义上下文选项:

ctx = ssl.create_default_context()

# 设置最低TLS版本
ctx.minimum_version = ssl.TLSVersion.TLSv1_2

# 设置密码套件
ctx.set_ciphers('ECDHE+AESGCM:!aNULL:!MD5')

# 禁用不安全的协议
ctx.options |= ssl.OP_NO_TLSv1
ctx.options |= ssl.OP_NO_TLSv1_1

TLS版本和密码套件的配置直接影响安全性。SSLv2/3已完全废弃。

安全客户端连接:

import socket
import ssl

hostname = 'example.com'
ctx = ssl.create_default_context()

with socket.create_connection((hostname, 443)) as sock:
with ctx.wrap_socket(sock, server_hostname=hostname) as ssock:
print(f"TLS version: {ssock.version()}")
print(f"Cipher: {ssock.cipher()}")
print(f"Certificate: {ssock.getpeercert()}")
ssock.sendall(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
data = ssock.read(1024)

wrap_socket将普通socket包装为TLS socket。server_hostname启用SNI和主机名校验。

证书验证细节:

cert = ssock.getpeercert()
if cert:
print(f"Subject: {dict(x[0] for x in cert['subject'])}")
print(f"Issuer: {dict(x[0] for x in cert['issuer'])}")
print(f"Valid from: {cert['notBefore']}")
print(f"Valid to: {cert['notAfter']}")
print(f"Serial: {cert['serialNumber']}")

getpeercert(binary_form=True)返回DER格式的原始证书。配合cryptography库深入解析。

自定义证书验证:

def verify_cert(conn, cert, errno, depth, ok):
if depth == 0: # 叶子证书
if cert.subject.get_attributes_for_oid('2.5.4.3')[0].value != 'example.com':
return False
return ok

ctx = ssl.create_default_context()
ctx.verify_flags = ssl.VERIFY_X509_STRICT
# 通过set_verify回调自定义验证逻辑

服务器端TLS:

import socket
import ssl

ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain('server.crt', 'server.key')

# 要求客户端证书
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.load_verify_locations('ca.crt')

with socket.socket() as sock:
sock.bind(('localhost', 8443))
sock.listen(5)
with ctx.wrap_socket(sock, server_side=True) as ssock:
conn, addr = ssock.accept()
# 处理连接

CERT_REQUIRED要求客户端提供证书。CERT_OPTIONAL接受但不强制。CERT_NONE不验证客户端证书。

内存中的证书加载:

# 从字符串加载证书
cert_pem = b"-----BEGIN CERTIFICATE-----\n..."
key_pem = b"-----BEGIN PRIVATE KEY-----\n..."
ctx.load_cert_chain(cadata=cert_pem, keyfile=key_pem)

# 从内存加载CA证书
ctx.load_verify_locations(cadata=cert_pem)

SSL上下文对象线程安全,但在多线程中应避免同时修改。

会话复用:

ctx.set_session_id(b"MyApplication")

# 创建会话对象
session = ssock.session

# 在新连接上复用会话
new_ssock.session = session

会话复用减少TLS握手次数,提升性能。

ALPN协议协商:

ctx.set_alpn_protocols(['h2', 'http/1.1'])
# 服务器端设置
# ctx.set_alpn_protocols(['h2', 'http/1.1'])

alpn = ssock.selected_alpn_protocol()
print(f"Negotiated: {alpn}") # 'h2'或'http/1.1'

ALPN(应用层协议协商)让TLS握手阶段商定上层协议。

SSL/TLS的最佳实践:

ctx = ssl.create_default_context()

# 禁用压缩(防止CRIME攻击)
ctx.options |= ssl.OP_NO_COMPRESSION

# 启用安全重协商
ctx.options |= ssl.OP_NO_RENEGOTIATION

# 设置DH参数(前向安全性)
# ctx.load_dh_params('dhparam.pem')

# 设置会话缓存
ctx.session_stats()

OP_NO_COMPRESSION防止CRIME攻击。OP_NO_RENEGOTIATION防止重新协商。DH参数提供完美前向安全性。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询