2012-12-04 18 views
10

Heute stand ich einem interessanten Problem gegenüber.Httplib2 ssl Fehler

ich die viereckig empfohlen Python-Bibliothek bin mit httplib2 erhöhen

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

bei dem Versuch, ein OAuth-Token anzufordern

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

in

_process_request_with_httplib2 function 

weiß jemand, warum dies geschieht ?

+3

Ich bin mir ziemlich sicher, dass die SSL-Zertifikat Überprüfung fehlgeschlagen **: - D ** – BorrajaX

Antwort

20

Wenn Sie wissen, dass die Website, die Sie versuchen, ein „guter Kerl“ zu bekommen ist, können Sie Ihre „Opener“, wie diese versuchen zu schaffen:

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") 

(der interessante Teil ist disable_ssl_certificate_validation=True)

Aus der Dokumentation: http://bitworking.org/projects/httplib2/doc/html/libhttplib2.html#httplib2.Http

EDIT 01:

Da Ihre Frage tatsächlich war, warum das passiert, können Sie this oder this überprüfen.

EDIT 02:

Zu sehen, wie diese Antwort wird von mehr Menschen besucht als ich erwartet hatte, würde Ich mag ein wenig zu erklären, wenn deaktivieren Zertifikatsvalidierung nützlich sein könnte.

Zuerst ein bisschen heller Hintergrund, wie diese Zertifikate funktionieren. Es gibt ziemlich viele Informationen in den oben angegebenen Links, aber hier geht es sowieso.

Die SSL-Zertifikate müssen von einem bekannten (mindestens so gut bekannten) Browser überprüft werden Certificate Authority. Sie kaufen in der Regel das gesamte Zertifikat von einer dieser Behörden (Symantec, GoDaddy ...)

Grob gesagt, die Idee ist: Diese Zertifizierungsstellen (CA) geben Sie ein Zertifikat, das enthält auch die CA-Information drin . Ihre Browser verfügen über eine Liste bekannter CAs. Wenn Ihr Browser ein Zertifikat empfängt, wird beispielsweise Folgendes ausgeführt: "HmmmMMMmmm .... [Der Browser erstellt hier ein positives Gesicht]... Ich habe eine empfangen Zertifikat, und es wird von Symantec verifiziert Ich weiß, dass "Symantec" Typ? [Der Browser geht dann zu seiner Liste der bekannten CAs und überprüft Symantec]Oh, yeah, ich tue das. Okay, die Zertifikat ist gut!

Sie diese Informationen selbst sehen können, wenn Sie von der URL in Ihrem Browser auf das kleine Schloss klicken:

Chrome certificate information

Allerdings gibt es Fälle, in denen Sie nur die HTTPS testen wollen, und Sie erstellen Ihre eigene Zertifizierungsstelle mit ein paar command line Tools, und Sie verwenden diese "benutzerdefinierte" Zertifizierungsstelle, um ein "benutzerdefiniertes" Zertifikat zu signieren, das Sie gerade erstellt haben, oder? In diesem Fall wird Ihr Browser (der übrigens in der Frage httplib2.Http ist) Ihre "benutzerdefinierte" Zertifizierungsstelle nicht in der Liste der vertrauenswürdigen Zertifizierungsstellen enthalten. Daher wird das Zertifikat als ungültig gekennzeichnet. Die Informationen werden immer noch verschlüsselt übertragen, aber der Browser sagt Ihnen, dass er nicht voll und ganz davon überzeugt ist, dass er verschlüsselt zu dem Ort transportiert wird, an dem er sich befindet.

Zum Beispiel lassen Sie uns sagen, dass Sie eine Reihe von benutzerdefinierten Schlüssel erstellt und CAs und alle mambo-Jumbo folgende this tutorial für Ihre localhostFQDN und dass Ihre CA-Zertifikat-Datei im aktuellen Verzeichnis befindet. Sie könnten sehr gut einen Server unter https://localhost:4443 mit Ihren benutzerdefinierten Zertifikaten und so weiter haben. Jetzt befindet sich Ihre CA-Zertifikatsdatei im aktuellen Verzeichnis in der Datei ./ca.crt (im selben Verzeichnis, in dem Ihr Python-Skript ausgeführt wird). Sie könnten wie folgt verwenden:

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

... und Sie würden die Warnung nicht mehr sehen. Warum? Weil Sie sagte für das Zertifikat der CA suchen gehen zu ./ca.crt)

Da jedoch Chrome (um einen Browser zu nennen) nicht weiß, über das Zertifikat dieser CA, wird es es für ungültig:

enter image description here

Auch Zertifikate verfallen. Es besteht die Möglichkeit, dass Sie in einem Unternehmen arbeiten, das eine interne Website mit SSL-Verschlüsselung verwendet. Es funktioniert für ein Jahr, und dann beginnt Ihr Browser sich zu beschweren. Sie gehen zu der Person, die für die Sicherheit zuständig ist, und fragen "Yo !! Ich bekomme diese Warnung hier! Was ist los?" Und die Antwort könnte sehr gut "Oh Junge !! Ich habe vergessen, das Zertifikat zu erneuern! Es ist in Ordnung, akzeptiere es einfach von jetzt an, bis ich das beheben." (wahre Geschichte, obwohl es Schimpfwörter in der Antwort waren erhielt ich :-D)

+3

Das ist wirklich keine gute Idee - Sie sollten wirklich herausfinden, warum Ihre Validierung fehlschlägt. Indem Sie die Validierung deaktivieren, entfernen Sie im Wesentlichen die Fähigkeit, viele Man-in-the-Middle-Angriffe zu erkennen, bei denen jemand den Upstream-Foursquare-Server imitieren möchte - Sie werden nicht einmal in der Lage sein, den einfachen Fall zu erkennen generierte ein selbstsigniertes Zertifikat. – javanix

+1

Bemerkung: um die Validierung des Zertifikats zu deaktivieren, wird nur 'h = httplib2.Http (disable_ssl_certificate_validation = True)' benötigt. –

+0

@javanix, daher die * Wenn Sie wissen, dass die Website, die Sie versuchen zu bekommen, ein "guter Typ" ist ... * – BorrajaX

10

Neuere Versionen von httplib2 seinen eigenen Zertifikatspeicher wird in Verzug.

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

Im Fall, wenn Sie Ubuntu/Debian verwenden, können Sie explizit den Pfad zu Systemzertifikatdatei übergeben wie

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