http如何使用SSL做双向认证

Posted by     "lxg" on Friday, June 20, 2025

生成证书

创建服务器端

import http.server
import ssl

# 硬编码私钥密码
SERVER_KEY_PASSWORD = ''

server_address = ('0.0.0.0', 8443)

httpd = http.server.HTTPServer(server_address, http.server.SimpleHTTPRequestHandler)

# 使用 SSLContext 支持密码
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile='server.pem', keyfile='server.key', password=SERVER_KEY_PASSWORD)
context.load_verify_locations(cafile='ca.pem')
context.verify_mode = ssl.CERT_REQUIRED  # 强制客户端认证

httpd.socket = context.wrap_socket(httpd.socket, server_side=True)

print("HTTPS Server running on port 8443 with mutual TLS and private key password...")
httpd.serve_forever()

创建客户端端

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
import ssl


CLIENT_KEY_PASSWORD = 'test'


class SSLAdapter(HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        context = create_urllib3_context()
        context.check_hostname = False
        context.verify_mode = ssl.CERT_REQUIRED
        context.load_cert_chain(certfile='client.pem', keyfile='client.key', password=CLIENT_KEY_PASSWORD)
        context.load_verify_locations(cafile='ca.pem')
        kwargs['ssl_context'] = context
        return super().init_poolmanager(*args, **kwargs)

session = requests.Session()
session.mount('https://', SSLAdapter())

try:
    response = session.get('https://localhost:8443', verify=False)
    print("Response status:", response.status_code)
    print(response.text)
except Exception as e:
    print(f"Error: {e}")