Python richiede la verifica SSL

2

Attualmente sto lavorando con il modulo Richieste in python, che ti permette di specificare un certificato SSL da usare nella tua richiesta, usando il seguente comando

url = r'https://www.google.com'
cert_path = r'C:\mystuff\google.crt'
requests.get(url, verify=cert_path)

Richieste memorizza le sue CA di fiducia in un file PEM situato in python / Lib / site-packages / requests / cacert.pem. Se si specifica 'verify = True', quindi cercherà cacert.pem.

Sto visualizzando il Cert per link tramite Chrome, e ha il seguente percorso cert.

GeoTrust Global CA - > Google Internet Authority G2 - > www.google.com

Quello che trovo strano è che quando estraggo tutti i certificati SSL relativi a GeoTrust dall'archivio cacert.pem, li metto nel proprio GeoTrust.pem e punti le richieste su quel file, l'handshake fallisce.

Tuttavia, attraverso tentativi ed errori, se rimuovo il primissimo cert SSL da cacerts.pem, che è "CA Equifax Secure", inseriscilo nel proprio file cert e, a tale scopo, la richiesta funziona perfettamente.

In sostanza, perché una richiesta che usa un certificato di GeoTrust viene negata contro una configurazione di URL con un certificato GeoTrust? E perché dovrebbe funzionare quando si specifica la radice di Equifax?

Ho anche provato a copiare direttamente da google tramite chrome il certificato di root GeoTrust come Base64, e lo aggiungo a GeoTrust.pem, ma l'handshake continua a fallire.

Sono nuovo, quindi qualsiasi aiuto sarebbe molto apprezzato

    
posta disflux 08.01.2016 - 19:39
fonte

1 risposta

4

I'm new to this, so any help would be greatly appreciated

Questo è in realtà un problema non solo per i principianti disperazione. Il problema è complesso e dipende da implementazioni e bug specifici nelle librerie TLS coinvolte. Quindi non è colpa tua se non funziona come previsto. Spero che la seguente spiegazione possa essere compresa:

Esistono diversi percorsi di fiducia per un certificato attendibile. Ciò che il server invia come certificati è questo:

#0 CN=www.google.com SAN=DNS:www.google.com
#1 CN=Google Internet Authority G2
#2 CN=GeoTrust Global CA

L'ultimo certificato è firmato da #3 OU=Equifax Secure Certificate Authority che non è incluso nella catena inviata dal server.

La libreria NSS utilizzata in Chrome e Firefox inizia nella parte superiore e controlla ogni certificato se è in grado di trovare una CA attendibile che ha firmato questo certificato, ovvero un certificato che esiste nel negozio di fiducia locale. Si fermerà con la convalida al certificato n. 1, perché ha un certificato locale per GeoTrust Global CA che può essere utilizzato per convalidare il certificato n. Così è fatto con la convalida e ignora il certificato n. 2.

OpenSSL fino alla versione 1.0.1 (almeno fino a 1.0.1 p) funziona in modo diverso. Analizzerà l'intera catena e cercherà di trovare un'ancora di fiducia per l'ultimo certificato della catena. Poiché spesso i server inviano il certificato radice all'interno della catena (che è errato) elimineranno tutti i certificati autofirmati dalla catena prima che cerchino l'ancoraggio attendibile (poiché i certificati radice sono solitamente autofirmati).

In questo caso il certificato n. 2 per "GeoTrust Global CA" non è un certificato autofirmato (firmato da Equifax) e non verrà rimosso. Cercherà quindi di trovare l'emittente per questo certificato n. 2 "GeoTrust Global CA" nel trust store per creare la catena di fiducia. Se hai incluso il certificato n. 3 (Equifax) nel trust store (nome file in verify parametro), allora tutto va bene e la convalida ha esito positivo. Se si include solo la "CA globale di GeoTrust" nell'archivio di fiducia, la convalida non riesce poiché questa non è l'ancora attendibile corretta per il certificato n. 2. OpenSSL 1.0.1 è troppo stupido per capire che questa sarebbe l'ancoraggio di fiducia perfetto per il certificato n. 1 e quindi la convalida fallisce.

La situazione è stata modificata alla fine (più di 3 anni dopo ho segnalato questo tipo di errore ) in OpenSSL 1.0.2. Se il primo tentativo di convalidare la catena fallisce, rimuoverà l'ultimo certificato dalla catena (certificato n. 2) e riprovare. In questo caso ci riuscirà. Ciò significa che se si utilizza una versione di Python creata con OpenSSL 1.0.2, allora dovrebbe andare bene. Per maggiori dettagli sui diversi modi di convalidare il percorso di fiducia vedi l'ultimo commento al bug # OpenSSL 3621 .

    
risposta data 08.01.2016 - 22:50
fonte

Leggi altre domande sui tag