Читання сертифіката вузла TLS через HTTP-проксі в Python
Використовуйте підтримку тунелю HTTPConnection у Python, перш ніж обгорнути сокет у перевіряльний контекст SSL.
ssl.get_server_certificate не узгоджує HTTP-проксі. Спершу встановіть тунель, потім виконайте TLS з іменем хоста призначення й отримайте сертифікат вузла.
Для HTTP-проксі без автентифікації, використовуючи хост і порт кандидата зі списку 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 обробляє запит CONNECT і відповідь на нього. Далі контекст SSL перевіряє ланцюг і справжність призначення, перш ніж сертифікат буде повернуто. Для цього рукостискання HTTP GET до призначення не потрібен.
Якщо середовище використовує схвалений приватний CA, завантажте цей CA в контекст замість вимкнення перевірки. Відхилений ланцюг спричиняє збій показаного рукостискання.
getpeercert повертає листовий сертифікат вузла, а не автоматично експортований повний ланцюг. У разі довіреного перехоплення TLS сертифікат вузла може бути сертифікатом, створеним посередником для цього імені хоста. Зберігайте цю різницю, порівнюючи його з сертифікатом, спостереженим іншим маршрутом.