Läs ett TLS-peer-certifikat genom en HTTP-proxy i Python
Använd Pythons HTTPConnection-tunnelstöd innan socketen lindas in i en validerande SSL-kontext.
ssl.get_server_certificate förhandlar inte med en HTTP-proxy. Upprätta först tunneln och utför sedan TLS med destinationsvärdens namn och hämta peer-certifikatet.
För en HTTP-proxy utan autentisering, med värd och port från en kandidat i HTTP-proxy-listan:
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 hanterar CONNECT-begäran och dess svar. SSL-kontexten verifierar sedan kedjan och destinationens identitet innan certifikatet returneras. Ingen HTTP GET till destinationen krävs för denna handskakning.
Om miljön använder en godkänd privat CA, ladda in den CA:n i kontexten i stället för att inaktivera verifiering. En avvisad kedja gör att den visade handskakningen misslyckas.
getpeercert returnerar peerens lövcertifikat, inte en automatiskt exporterad fullständig kedja. Vid betrodd TLS-avlyssning kan peer-certifikatet vara det certifikat som mellanhanden genererat för detta värdnamn. Behåll den skillnaden när du jämför det med ett certifikat som observerats via en annan väg.