2016-07-03 19 views
1

Ich versuche, ein Stück Code zu verstehen, der HostnameVerifier und SSLSocketFactory für HttpsURLConnection nicht überschreibt. Der aktuelle Code ist in der Lage, die SSL-Anfrage in Ordnung zu bringen, was für mich etwas verwirrend ist. Wie funktioniert die Standardimplementierung der Klassen HostnameVerifier und SSLSocketFactory? Überprüft es die Zertifikats-CA und den Hostnamen oder umgeht es alle diese Prüfungen?Verhalten von HttpsURLConnectioin mit der Standardimplementierung von HostnameVerifier und SSLSocketFactory

Gibt es auch ein spezielles Verhalten, wenn die Anfrage localhost hat? Die URL sieht wie folgt aus
https://localhost:/

Vielen Dank für Ihre Hilfe.

Antwort

2

Es überprüft das CA-Zertifikat auf die vertrauenswürdigen CA-Zertifikate im vertrauenswürdigen Speicher des JDK oder was auch immer Sie konfiguriert haben.

Es wird auch überprüft, dass alle Zertifikate in der Kette vertrauenswürdig sind, nicht nur den unmittelbaren Unterzeichner. Es wird standardmäßig nicht online nach gesperrten Zertifikaten suchen, aber Sie können das in der java.security Richtliniendatei aktivieren.

Es wird auch der Hostname für das Zertifikat überprüfen. Es unterstützt zusätzliche CNs und Wildcard-CNs.

Erweiterte Frage zu localhost:

localhost ist nur ein Host-Name wie jeder andere. Es muss im Zertifikat aufgeführt sein. Aber du wirst keine offizielle CA finden, die dir dieses Zertifikat gibt, denke ich :-)

Wenn du mit deinem echten Cert auf localhost spielen willst, adressierst du es mit einem anderen Hostnamen. Wenn Sie foo.bar.com durch ein cert ausführen möchten, fügen Sie Ihre hosts Datei (Win: %WINDOWS%\system32\drivers\etc\hosts, Unix /etc/hosts) die Zeile:

127.0.0.1 foo.bar.com 

Jetzt Ihrem Browser anwerfen und eine Verbindung zu https://foo.bar.com. Es stellt eine Verbindung zu Ihrem lokalen Server her und sendet eine SSL-verschlüsselte HTTP-Anfrage. Diese Anfrage enthält den Hostnamen von der URL, nicht den echten Hostnamen.

Ich war übermäßig kompliziert: Der Browser empfängt das SSL-Zertifikat vom Server und vergleicht den CN mit dem Hostnamen, den er gerade angerufen hat. Wenn dies zutrifft, prüft es, ob das Zertifikat vertrauenswürdig ist (verlange nicht die Reihenfolge, vielleicht überprüft es zuerst den Trustlevel).

Hier ist der Fehler: Das vom Server bereitgestellte Zertifikat enthält den CN localhost nicht, und daher bricht der Client die Verbindung ab. In Ihrem Fall ist der Client der HttpSSLrequest.

Damit der Client glaubt, dass alles in Ordnung ist, können Sie zwei Dinge tun: - den Hostnamen fälschen und die Signatur-CA in den cacerts-Truststore einfügen. - Implementieren Sie einen Hostnamen und Zertifikatsvalidierer, der Sie durchlässt.

In Bezug auf das Lernprogramm wird ein selbstsigniertes Zertifikat verwendet. Sie müssen den Browser davon überzeugen, dies zu akzeptieren, indem Sie die Warnung beim ersten Zugriff überschreiben.

+0

In welcher Konfiguration sollte ich suchen? Ich bin nicht sicher, wo der Standard-Truststore für JDK festgelegt ist. – user1549994

+0

"Es unterstützt zusätzliche CNs und Wildcard-CNs.".Was meinst du mit Wildcard CNs. Wird localhost als Platzhalter CN betrachtet? Die gesendete Anforderung verwendet den lokalen Host, aber das Zertifikat, das der Server zurücksendet, enthält keinen "localhost". – user1549994

+0

Ein Platzhalter-Cert enthält ein Sternchen und funktioniert für alle Subdomains dieser Domain: '* .foo.com' funktioniert für' bar.foo.com', 'baz.foo.com' usw. Wenn Sie mit localhost spielen möchten, füge es dem Zertifikat hinzu. Siehe meine Antwort. – thst