Wie Verwenden von Httpclient mit jedem SSL-Zertifikat, egal wie „schlecht“ es ist


Brad Parks:

Ich verwende Apache Httpclient in einem Web - Crawler, der nur für das Crawling öffentliche Daten.

Ich möchte es mit ungültigen Zertifikaten zu kriechen Websites der Lage sein, unabhängig davon, wie ungültig.

Mein Crawler nicht in irgendwelchen Benutzernamen, Passwörter werden vorbei, etc. und keine sensiblen Daten gesendet oder empfangen werden.

Für diesen Anwendungsfall, würde ich die kriechen httpVersion einer Website , wenn es vorhanden ist , aber manchmal tut es natürlich nicht.

Wie kann dies mit getan werden Apache Httpclient ?

Ich habe versucht , ein paar Vorschläge , wie diese , aber sie scheitern , noch für einige ungültige Zertifikate, zum Beispiel:

failed for url:https://dh480.badssl.com/, reason:java.lang.RuntimeException: Could not generate DH keypair
failed for url:https://null.badssl.com/, reason:Received fatal alert: handshake_failure
failed for url:https://rc4-md5.badssl.com/, reason:Received fatal alert: handshake_failure
failed for url:https://rc4.badssl.com/, reason:Received fatal alert: handshake_failure
failed for url:https://superfish.badssl.com/, reason:Connection reset

Beachten Sie, dass ich das versucht habe , mit meiner $JAVA_HOME/jre/lib/security/java.securityDatei jdk.tls.disabledAlgorithmsSatz zu nichts, dies ist kein Problem , um sicherzustellen, und ich immer noch Ausfälle wie die oben erhalten.

user3474985:

Die kurze Antwort auf Ihre Frage, die speziell ist, alle certs zu vertrauen, wäre es , die verwenden TrustAllStrategy und etwas zu tun , wie folgt aus :

SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
sslContextBuilder.loadTrustMaterial(null, new TrustAllStrategy());
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
        sslContextBuilder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
        socketFactory).build();

Allerdings ... ein ungültiges Zertifikat nicht erlaubt, Ihr Hauptproblem sein. Ein handshake_failure kann für eine Reihe von Gründen auftreten , aber in meiner Erfahrung ist es in der Regel aufgrund eines SSL / TLS - Versionskonflikt oder Cipher Suite Aushandlungsfehler. Dies bedeutet nicht , das SSL - Zertifikat ist „schlecht“, es ist nur ein Konflikt zwischen dem Server und Client. Sie können genau sehen , wo die Handshake - Fehler wird mit einem Tool wie Wireshark ( mehr dazu )

Während Wireshark kann groß sein , um zu sehen , wo es versagt, wird es Ihnen helfen, mit einer Lösung nicht kommen. Jedes Mal , wenn ich über das Debuggen handshake_failures in der Vergangenheit ich bin gegangen , habe festgestellt , dieses Tool besonders hilfreich: https://testssl.sh/

Sie können an jedem Ihrer Fehler-Websites, dass Skript zu verweisen, um zu erfahren, welche Protokolle auf diesem Ziel verfügbar sind und was Ihr Kunde braucht Unterstützung, um einen erfolgreichen Handshake zu etablieren. Es wird auch Informationen über das Zertifikat auszudrucken.

Zum Beispiel (zeigt nur zwei Abschnitte der Ausgabe des testssl.sh):

./testssl.sh www.google.com
....
 Testing protocols (via sockets except TLS 1.2, SPDY+HTTP2) 

 SSLv2               not offered (OK)
 SSLv3               not offered (OK)
 TLS 1               offered
 TLS 1.1             offered
 TLS 1.2             offered (OK)
 ....
Server Certificate #1
   Signature Algorithm          SHA256 with RSA
   Server key size              RSA 2048 bits
   Common Name (CN)             "www.google.com"
   subjectAltName (SAN)         "www.google.com" 
   Issuer                       "Google Internet Authority G3" ("Google Trust Services" from "US")
   Trust (hostname)             Ok via SAN and CN (works w/o SNI)
   Chain of trust               "/etc/*.pem" cannot be found / not readable
   Certificate Expiration       expires < 60 days (58) (2018-10-30 06:14 --> 2019-01-22 06:14 -0700)
 ....
 Testing all 102 locally available ciphers against the server, ordered by encryption strength 
(Your /usr/bin/openssl cannot show DH/ECDH bits)

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.  Encryption Bits
------------------------------------------------------------------------
xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH       AESGCM    256       
xc02c   ECDHE-ECDSA-AES256-GCM-SHA384     ECDH       AESGCM    256       
xc014   ECDHE-RSA-AES256-SHA              ECDH       AES       256       
xc00a   ECDHE-ECDSA-AES256-SHA            ECDH       AES       256       
x9d     AES256-GCM-SHA384                 RSA        AESGCM    256       
x35     AES256-SHA                        RSA        AES       256       
xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH       AESGCM    128       
xc02b   ECDHE-ECDSA-AES128-GCM-SHA256     ECDH       AESGCM    128       
xc013   ECDHE-RSA-AES128-SHA              ECDH       AES       128       
xc009   ECDHE-ECDSA-AES128-SHA            ECDH       AES       128       
x9c     AES128-GCM-SHA256                 RSA        AESGCM    128       
x2f     AES128-SHA                        RSA        AES       128       
x0a     DES-CBC3-SHA                      RSA        3DES      168 

So diese Ausgabe verwenden , können wir sehen , dass , wenn Ihr Kunde SSLv3 nur unterstützt, würde die Handshake fehlschlagen , da das Protokoll vom Server nicht unterstützt wird. Das Protokoll - Angebot ist unwahrscheinlich , dass das Problem , aber Sie können überprüfen Sie, was Ihr Java - Client unterstützt durch die Liste der aktivierten Protokolle zu bekommen. Sie können eine überschriebene Implementierung des SSLConnectionSocketFactory von oben Code - Schnipsel bieten die Liste der aktivierten / unterstützten Protokolle und Chiffriersätze wie folgt zu erhalten ( SSLSocket ):

class MySSLConnectionSocketFactory extends SSLConnectionSocketFactory {
    @Override
    protected void prepareSocket(SSLSocket socket) throws IOException {
        System.out.println("Supported Ciphers" + Arrays.toString(socket.getSupportedCipherSuites()));
        System.out.println("Supported Protocols" + Arrays.toString(socket.getSupportedProtocols()));
        System.out.println("Enabled Ciphers" + Arrays.toString(socket.getEnabledCipherSuites()));
        System.out.println("Enabled Protocols" + Arrays.toString(socket.getEnabledProtocols()));
    }
}

Ich begegne oft handshake_failure, wenn es eine Chiffre-Suite Aushandlungsfehler ist. Um diesen Fehler zu vermeiden, Ihre Kunden Liste der unterstützten Chiffriersätze muss mindestens ein Spiel zu einer Chiffre-Suite enthalten aus der Liste der Server der unterstützten Chiffriersätze.

Wenn der Server AES256 basierte Chiffre erfordert Suiten müssen Sie wahrscheinlich die Java-Verschlüsselungs Erweiterungen (JCE). Diese Bibliotheken sind Nation beschränkt, so dass sie nicht an jemanden außerhalb der USA verfügbar.

Mehr über Kryptographie Einschränkungen, wenn Sie interessiert sind : https://crypto.stackexchange.com/questions/20524/why-there-are-limitations-on-using-encryption-with-keys-beyond-certain-length

Verwandte Artikel


Ist es schlecht, Polling in Java zu verwenden?

Arturs Vancans: Ich habe mehrere, ArrayListsdie als Datenwarteschlangen arbeiten. Jede der Warteschlangen ist mit einem einzelnen Thread verknüpft, der prüft, ob darin ArrayListDaten enthalten sind. while (array.size == 0) { // nothing } // do stuff wi

Ist es manchmal schlecht, <BR /> zu verwenden?

Bleistiftkuchen Ist es manchmal schlecht, <BR/>Tags zu verwenden ? Ich frage, weil einige der ersten Ratschläge, die mir mein Entwicklungsteam gab, folgende waren: Nicht verwenden <BR/>; Verwenden Sie stattdessen Stile. Aber warum? Gibt es negative Ergebnisse

Wie schlecht ist es, viele kleine Kernel in CUDA zu starten?

Michael Ich habe ein Gitter von Rechtecken. Jedes dieser Rechtecke besteht aus einem rechteckigen Punktgitter. Alle Punkte innerhalb des Rechtecks können durch genau dieselbe Befehlssequenz in einem Kernel behandelt werden. Ich werde in der Lage sein, einen Ke

Wie schlecht ist es, globale Variablen in nodejs zu verwenden?

abel Miete Ich brauche Bibliotheken (Mongo, Async ...) und einige Kernfunktionen in fast allen Dateien meines Codes. Soweit ich weiß, ist das Laden eines Moduls ein teurer Prozess. Außerdem ist das Schreiben von x weiteren Codezeilen in jede Datei ein Problem.

Wie heißt diese Programmiermethode? Und ist es schlecht?

Luminary Promotions In letzter Zeit habe ich in meinen Unity-Projekten festgestellt, dass es zum Erstellen einer modulareren Anwendung hilfreich ist, eine statische Liste in einer Klasse zu haben, die Verweise auf alle oder einige der erstellten Objekte enthäl

Wie verwende ich ein SSL-Zertifikat mit Swift Alamofire?

DRP Ich aktualisiere meine iOS-Apps mit HTTPS-Webdiensten. Ich habe meinen Webserver mit einem SSL-Zertifikat aktualisiert. Aber wissen Sie nicht, was Sie von der iOS-Codeseite aus tun sollen? Muss ich ein Zertifikat zusammen mit der Webanforderung übergeben?

Wie erhalte ich ein SSL-Zertifikat von ACM mit android aws sdk?

Sidharth MA Ich versuche, ein SSL-Zertifikat von ACM abzurufen, kann dies jedoch nicht. Ich habe versucht, das alte aws-java-sdk-acm zu verwenden, aber es hat einen http-Client, der nicht mehr verwendet werden kann. Daher kann ich das Zertifikat nicht von der

Warum ist es schlecht, kurz zu verwenden

Edenia Es kommt sehr häufig vor, dass selbst in Skripten, in denen der Entwickler garantiert, dass die Variable niemals ein Byte und manchmal zwei Bytes überschreitet. Viele Menschen entscheiden sich dafür, intTypen für jede mögliche Variable zu verwenden, die

Wie installiere ich ein SSL-Zertifikat von goDaddy in nodejs?

Santhosh D. Ich habe ein Zertifikat von Godaddy gekauft und es muss auf unserem NodeJS-Server installiert werden. Ich habe den folgenden Code geschrieben. Dies hat früher funktioniert, aber wir haben kürzlich das Zertifikat erneuert und die alten Zertifikate d

Wie soll ich ein Zertifikat mit HttpClient verwenden?

Torben Nielsen Ich muss eine Web-API von einem unserer Partner verwenden. Ihre API erfordert, dass ich ein Zertifikat verwende, um eine Verbindung herzustellen. Ich möchte das Zertifikat nicht auf unseren Servern (VMs) installieren. Das ist kontraproduktiv für

Privates Zertifikat anfordern ist deaktiviert: Wie kommt es?

Phat Ich versuche, ein privates Zertifikat über den AWS Certificate Manager zu generieren, aber anscheinend kann ich nur ein öffentliches anfordern. Ist dafür eine Genehmigung erforderlich? Mein Konto sollte vollen Zugriff auf alles haben... Ivan Schumov Nein,

Wie erstelle ich ein selbstsigniertes SSL-Zertifikat mit OpenSSL?

michelemarcon Ich füge HTTPS-Unterstützung zu einem eingebetteten Linux-Gerät hinzu. Ich habe versucht, mit diesen Schritten ein selbstsigniertes Zertifikat zu generieren: openssl req -new > cert.csr openssl rsa -in privkey.pem -out key.pem openssl x509 -in ce