Comment utiliser HttpClient avec TOUT cert ssl, quelle que soit la « mauvaise » est
J'utilise Apache HttpClient dans un robot Web qui est seulement pour l' exploration des données publiques.
Je voudrais qu'il soit en mesure de les sites d'exploration avec des certificats non valides, peu importe comment invalide.
Mon robot ne sera pas passe dans tous les noms d'utilisateur, mots de passe, etc. et aucune donnée sensible est envoyé ou reçu.
Pour ce cas d'utilisation, je ramper la http
version d'un site si elle existe, mais parfois non bien sûr.
Comment cela peut - il être fait avec Apache HttpClient ?
J'ai essayé quelques suggestions comme celui - ci , mais ils ne parviennent toujours à quelques certs invalides, par exemple:
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
Notez que je l' ai essayé avec mon $JAVA_HOME/jre/lib/security/java.security
de fichier jdk.tls.disabledAlgorithms
de jeu à rien, pour que tel soit pas un problème, et je reçois encore des échecs comme ci - dessus.
La réponse courte à votre question, qui est de faire confiance spécifiquement tous certs, serait d'utiliser la TrustAllStrategy et faire quelque chose comme ceci:
SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
sslContextBuilder.loadTrustMaterial(null, new TrustAllStrategy());
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
sslContextBuilder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
socketFactory).build();
Mais ... un cert invalide ne peut pas être votre principal problème. Un handshake_failure peut se produire pour plusieurs raisons , mais dans mon expérience , il est généralement due à un SSL / TLS incompatibilité de version ou de l' échec de la négociation de suite de chiffrement. Cela ne signifie pas que le certificat ssl est « mauvais », il est juste un décalage entre le serveur et le client. Vous pouvez voir exactement où la poignée de main ne parvient pas à l' aide d' un outil comme Wireshark ( plus à ce sujet )
Alors que Wireshark peut être génial de voir où il est défaillant, il ne sera pas vous aider à trouver une solution. Chaque fois que je suis allé sur le débogage handshake_failures dans le passé , j'ai trouvé cet outil particulièrement utile: https://testssl.sh/
Vous pouvez indiquer ce script à l'un de vos sites à défaut d'en savoir plus sur quels protocoles sont disponibles sur cet objectif et ce que vos besoins de clients à l'appui afin d'établir une poignée de main avec succès. Il imprimera également des informations sur le certificat.
Par exemple (ne possédant que deux sections de la sortie de 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
Donc , en utilisant cette sortie , nous pouvons voir que si votre client pris en charge uniquement SSLv3, la poignée de main échouerait parce que ce protocole est pas pris en charge par le serveur. L'offre de protocole est peu probable que le problème , mais vous pouvez vérifiez ce que votre client Java prend en charge en obtenant la liste des protocoles activés. Vous pouvez fournir une implémentation surchargée du SSLConnectionSocketFactory de l' extrait de code ci - dessus pour obtenir la liste des permis / protocoles pris en charge et les suites de chiffrement comme suit ( 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()));
}
}
Je rencontre souvent handshake_failure quand il y a un échec de la négociation d'une suite de chiffrement. Pour éviter cette erreur, la liste de votre client de suites de chiffrement pris en charge doit contenir au moins un match à une suite de chiffrement de la liste du serveur de suites de chiffrement prises en charge.
Si le serveur requiert des suites de chiffrement AES256 base dont vous avez besoin probablement les extensions de chiffrement Java (JCE). Ces bibliothèques sont la nation limitée et peuvent ne pas être disponibles à quelqu'un en dehors des États-Unis.
Plus sur les restrictions de cryptographie, si vous êtes intéressé: https://crypto.stackexchange.com/questions/20524/why-there-are-limitations-on-using-encryption-with-keys-beyond-certain-length