ssl.get_server_certificate không thương lượng với proxy HTTP. Hãy thiết lập đường hầm trước, sau đó thực hiện TLS với tên máy chủ đích và lấy chứng chỉ peer.

Với proxy HTTP không cần xác thực, dùng máy chủ và cổng của một ứng viên từ danh sách proxy HTTP:

from contextlib import closing
import http.client
import ssl

hostname = "example.com"
context = ssl.create_default_context()

with closing(http.client.HTTPConnection(
    "proxy.example.net", 8080, timeout=10
)) as connection:
    connection.set_tunnel(hostname, 443)
    connection.connect()

    with context.wrap_socket(
        connection.sock, server_hostname=hostname
    ) as tls:
        certificate_der = tls.getpeercert(binary_form=True)

certificate_pem = ssl.DER_cert_to_PEM_cert(certificate_der)

HTTPConnection xử lý yêu cầu CONNECT và phản hồi của nó. Sau đó ngữ cảnh SSL xác minh chuỗi và danh tính đích trước khi chứng chỉ được trả về. Không cần HTTP GET tới đích cho bắt tay này.

Nếu môi trường dùng CA riêng đã được phê duyệt, hãy nạp CA đó vào ngữ cảnh thay vì tắt xác minh. Chuỗi bị từ chối khiến bắt tay hiển thị thất bại.

getpeercert trả về chứng chỉ lá của peer, không phải toàn bộ chuỗi được xuất tự động. Với chặn TLS đáng tin cậy, chứng chỉ peer có thể là chứng chỉ do trung gian tạo cho tên máy chủ này. Giữ sự khác biệt đó khi so sánh với chứng chỉ quan sát được qua tuyến khác.

Bài viết liên quan