Wie soll ich bei Verwendung von JSSE die Überprüfung des Hostnamens durchführen?

Ich schreibe einen Client in Java (muss sowohl auf dem Desktop-JRE als auch auf Android funktionieren) für ein proprietäres Protokoll (spezifisch für mein Unternehmen), das über TLS übertragen wird. Ich versuche herauszufinden, wie ein TLS-Client in Java am besten geschrieben werden kann, und stelle insbesondere sicher, dass die Überprüfung des Hostnamens ordnungsgemäß durchgeführt wird. (Bearbeiten: Damit meine ich zu überprüfen, ob der Hostname mit dem X.509-Zertifikat übereinstimmt, um Man-in-the-Middle-Angriffe zu vermeiden.)

JSSE ist die naheliegende API zum Schreiben eines TLS-Clients, aber ich habeDer gefährlichste Code der Welt"Papier (sowie aus Experimenten), dass JSSE den Hostnamen nicht validiert, wenn man die SSLSocketFactory API verwendet. (Was ich verwenden muss, da mein Protokoll nicht HTTPS ist.)

Es scheint also, dass ich bei Verwendung von JSSE die Hostnamenvalidierung selbst durchführen muss. Und anstatt den Code von Grund auf neu zu schreiben (da ich ihn mit ziemlicher Sicherheit falsch verstehen würde), sollte ich mir anscheinend einen vorhandenen Code "ausleihen", der funktioniert. Der wahrscheinlichste Kandidat, den ich gefunden habe, ist die Verwendung der Apache HttpComponents-Bibliothek (ironisch, da ich eigentlich kein HTTP mache).und verwenden Sie die Klasse org.apache.http.conn.ssl.SSLSocketFactory anstelle der Standardklasse javax.net.ssl.SSLSocketFactory.

Meine Frage ist: Ist dies eine vernünftige Vorgehensweise? Oder habe ich Dinge völlig missverstanden, bin vom Ende weggegangen und es gibt tatsächlich einen viel einfacheren Weg, um eine Hostnamenvalidierung in JSSE zu erhalten, ohne eine Bibliothek von Drittanbietern wie HttpComponents einzulesen?

Ich habe mir auch BouncyCastle angeschaut, das eine Nicht-JSSE-API für TLS hat, aber es scheint noch eingeschränkter zu sein, da es nicht einmal die Überprüfung der Zertifikatskette durchführt, geschweige denn die Überprüfung des Hostnamens -Anlasser.

Bearbeiten: Diese Fragewurde beantwortet für Java 7, aber ich bin immer noch gespannt, was die "Best Practice" für Java 6 und Android ist. (Insbesondere muss ich Android für meine Anwendung unterstützen.)

Erneut bearbeitet: Um meinen Vorschlag "von Apache HttpComponents ausleihen" konkreter zu machen, habe ich einekleine Bibliothek Dies enthält die HostnameVerifier-Implementierungen (insbesondere StrictHostnameVerifier und BrowserCompatHostnameVerifier), die aus Apache HttpComponents extrahiert wurden. (Ich erkannte, dass ich nur die Verifizierer benötige und nicht Apaches SSLSocketFactory, wie ich ursprünglich gedacht hatte.) Wenn ich es meinen eigenen Geräten überlasse, ist dies die Lösung, die ich verwenden werde. Aber erstens, gibt es einen Grund, warum ichsollte nicht mach es so (Unter der Annahme, dass mein Ziel darin besteht, die Validierung meines Hostnamens auf die gleiche Weise wie bei https durchzuführen. Mir ist klar, dass er offen für Diskussionen ist und in dem Thread auf der Kryptografieliste erörtert wurde, aber ich bleibe vorerst bei dem HTTPS-ähnlichen Hostnamen Validierung, obwohl ich kein HTTPS mache.)

Angenommen, es ist nichts "Falsches" an meiner Lösung, dann lautet meine Frage: Gibt es eine "bessere" Möglichkeit, dies zu tun, während ich auf Java 6, Java 7 und Android portabel bleibe? (Wo "besser" mehr Redewendungen bedeutet, die bereits weit verbreitet sind und / oder weniger externen Code benötigen.)

Antworten auf die Frage(2)

Ihre Antwort auf die Frage