2012-12-04 12 views
10

Oggi ho affrontato un problema interessante.Httplib2 ssl error

Sto utilizzando la libreria Python foursquare raccomandato httplib2 sollevare

SSLHandshakeError(SSLError(1, '_ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed'),) 

durante il tentativo di richiedere un token OAuth

response, body = h.request(url, method, headers=headers, body=data) 

in

_process_request_with_httplib2 function 

qualcuno sa perché questo accade ?

+3

Sono abbastanza sicuro che la verifica del certificato SSL non è riuscita **: - D ** – BorrajaX

risposta

20

Se si sa che il sito che si sta cercando di ottenere è un "bravo ragazzo", si può provare a creare il "opener" come questo:

import httplib2 
if __name__ == "__main__": 
    h = httplib2.Http(".cache", disable_ssl_certificate_validation=True) 
    resp, content = h.request("https://site/whose/certificate/is/bad/", "GET") 

(la parte interessante è disable_ssl_certificate_validation=True)

Dalla documentazione: http://bitworking.org/projects/httplib2/doc/html/libhttplib2.html#httplib2.Http

EDIT 01:

Poiché la tua domanda era in realtà perché ciò accade, puoi controllare this o this.

EDIT 02:

Vedendo come questa risposta è stata visitata da più persone di quanto mi aspettassi, mi piacerebbe spiegare un po 'quando disabilitando la convalida del certificato potrebbe essere utile.

In primo luogo, un leggero background su come funzionano questi certificati. C'è un sacco di informazioni nei link sopra, ma qui va, comunque.

I certificati SSL devono essere verificati da un noto (almeno, noto al browser) Certificate Authority. Di solito si acquista l'intero certificato da una delle dette autorità (Symantec, GoDaddy ...)

A grandi linee, l'idea è: tali autorità di certificazione (CA) si invia un certificato che contiene anche le informazioni CA in esso . I tuoi browser hanno un elenco di CA ben conosciute, quindi quando il tuo browser riceve un certificato, farà qualcosa del tipo: "HmmmMMMmmm .... [il browser fa una faccia suprema qui]... Ho ricevuto un certificato, e dice che è verificato da Symantec. So che il tipo "Symantec"? [il browser passa quindi all'elenco di CA ben noto e controlla Symantec]Oh, sì! Sì. Ok, il il certificato è buono!

Si può vedere che le informazioni da soli se si fa clic sul piccolo blocco da parte del URL nel browser:

Chrome certificate information

Tuttavia, ci sono casi in cui si desidera solo per testare il protocollo HTTPS, e si crea la propria Autorità di certificazione utilizzando un paio di strumenti command line e si utilizza quella CA "personalizzata" per firmare un certificato "personalizzato" appena generato, giusto? In tal caso, il tuo browser (che, a proposito, nella domanda è httplib2.Http) non avrà la tua "custom" CA tra l'elenco delle CA di fiducia, quindi dirà che il certificato non è valido. Le informazioni continueranno a viaggiare crittografate, ma ciò che il browser ti sta dicendo è che non è del tutto sicuro che viaggino crittografati nel luogo in cui pensi che stia andando.

Per esempio, diciamo che si è creato un set di chiavi personalizzate e CA e tutto il mambo-jumbo seguente this tutorial per il vostro localhostFQDN e che il file del certificato CA si trova nella directory corrente. Si potrebbe benissimo avere un server in esecuzione su https://localhost:4443 utilizzando i certificati personalizzati e quant'altro. Ora il file del certificato CA si trova nella directory corrente, nel file ./ca.crt (nella stessa directory in cui verrà eseguito lo script Python). Si potrebbe utilizzare come questo:

h = httplib2.Http(ca_certs='./ca.crt') 
response, body = h.request('https://localhost:4443') 
print(response) 
print(body) 

... e non si sarebbe più vedere l'avviso. Perché? Perché hai detto per andare a cercare il certificato del CA per ./ca.crt)

Tuttavia, dal momento che Chrome (per citare un browser) non conosce il certificato di questo CA, prenderà in considerazione è valida:

enter image description here

Inoltre, i certificati scadono. C'è una possibilità che tu stia lavorando in una società che utilizza un sito interno con crittografia SSL. Funziona bene per un anno, e quindi il tuo browser inizia a lamentarsi. Vai alla persona che si occupa della sicurezza e chiedi "Yo !! Ho ricevuto questo avviso qui! Cosa sta succedendo?" E la risposta potrebbe benissimo essere "Oh ragazzo !! Ho dimenticato di rinnovare il certificato! Va bene, accettalo da ora, finché non lo aggiusto". (storia vera, anche se c'erano parolacce nella risposta che ho ricevuto :-D)

+3

Questa non è davvero una grande idea - dovresti davvero capire perché la tua validazione stia fallendo. Disabilitando la convalida, si sta essenzialmente eliminando la possibilità di rilevare molti attacchi man-in-the-middle, in cui qualcuno vuole impersonare il server Foursquare a monte - non sarà possibile rilevare nemmeno il caso semplice in cui hanno generato un certificato autofirmato. – javanix

+1

Nota: per disabilitare la convalida del certificato è necessario 'h = httplib2.Http (disable_ssl_certificate_validation = True)' necessario. –

+0

@javanix, da cui il * Se sai che il sito che stai cercando di ottenere è un "bravo ragazzo" ... * – BorrajaX

10

versioni recenti di httplib2 è inadempiente al proprio archivio certificati.

# Default CA certificates file bundled with httplib2. 
CA_CERTS = os.path.join(
    os.path.dirname(os.path.abspath(__file__)), "cacerts.txt") 

Nel caso in cui se si sta utilizzando Ubuntu/Debian, è possibile passare in modo esplicito il percorso del file di certificato sistema come il

httplib2.HTTPSConnectionWithTimeout(HOST, ca_certs="/etc/ssl/certs/ca-certificates.crt")