Python에서 HTTP 프록시를 통해 TLS 피어 인증서 읽기
검증하는 SSL 컨텍스트로 소켓을 감싸기 전에 Python의 HTTPConnection 터널 지원을 사용합니다.
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 가로채기에서는 피어 인증서가 중간자에 의해 이 호스트 이름용으로 생성된 인증서일 수 있습니다. 다른 경로로 관찰한 인증서와 비교할 때 그 차이를 유지하십시오.