J'essaie d'établir une connexion à trackobot.com pour recevoir des données JSON. Le serveur n'autorise que les connexions via HTTPS/SSL. Voici le code:
Java.lang.System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
URL url = new URL("https://trackobot.com/profile/history.json?username=USER&token=TOCKEN");
InputStream is = url.openStream();
JsonParser parser = Json.createParser(is);
openSteam lève javax.net.ssl.SSLHandshakeException: alerte fatale reçue: handshake_failure
J'ai lu plusieurs articles liés à des problèmes similaires, mais aucune des suggestions n'a aidé. Le certificat approprié est dans mon magasin de clés de confiance. Lorsque j'essaie de me connecter à Google.fr, par exemple, il n'y a pas d'erreur. Ainsi, le problème semble être lié à la poignée de main du serveur auquel je tente de me connecter.
J'ai exécuté mon code en utilisant -Djavax.net.debug = ssl en renvoyant ceci:
keyStore is :
keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
trustStore is: /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/security/cacerts
trustStore type is : jks
trustStore provider is :
init truststore
[Here I removed hundreds of „adding as trusted cert“:… lines]
trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, setSoTimeout(0) called
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie: GMT: 1433943269 bytes = { 109, 198, 189, 148, 62, 6, 19, 126, 179, 214, 250, 99, 207, 117, 162, 47, 62, 176, 222, 247, 98, 29, 155, 63, 255, 100, 171, 187 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
Extension server_name, server_name: [type=Host_name (0), value=trackobot.com]
***
main, WRITE: TLSv1.2 Handshake, length = 229
main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1.2 ALERT: fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at Sun.security.ssl.Alerts.getSSLException(Alerts.Java:192)
at Sun.security.ssl.Alerts.getSSLException(Alerts.Java:154)
at Sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.Java:1991)
at Sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.Java:1104)
at Sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.Java:1343)
at Sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1371)
at Sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1355)
at Sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.Java:563)
at Sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.Java:185)
at Sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.Java:1511)
at Sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.Java:1439)
at Sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.Java:254)
at Java.net.URL.openStream(URL.Java:1038)
at trackbot.readHistory(trackbot.Java:37)
at hsanalytics.main(hsanalytics.Java:6)
Ende
De plus, j'utilise openssl et un script Perl (analyse-ssl.pl) pour vérifier le serveur.
Pour openssl s_client -connect trackobot.com:443 j'ai eu:
CONNECTED(00000003)
depth=2 /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
0 s:/C=CH/CN=www.trackobot.com/emailAddress=df1c792ce8e2fc342c0c63c2fab9c6fe-1805689@contact.gandi.net
i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
1 s:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
2 s:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGaTCCBVGgAwIBAgIHBaEI9iSK1jANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UE
BhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBE
aWdpdGFsIENlcnRpZm
[...]
bnCZTkntRP7wPfw6DpPdJzt8BD0Rpp0B8fVUkqkUujP
FEgspzHXqvAp3gzDuNVlElZ4pxSC/06x9xlPua4KnnKIPMVK0DjyXKdPgUaw6YH9
I3SprrGd/B5AoxdPYDM1qRGC+hto3YDnAb29CRFx13mfiEF9En6YrmlZMwJ/dMjo
RcvkqpjoxTLODmX9gWgdJ27Ublq/4f/Q9nlVfx4v00eYyqyMYY6IMlOUWEBvWoAv
zorzLLY9PmepXJtkCw==
-----END CERTIFICATE-----
subject=/C=CH/CN=www.trackobot.com/emailAddress=df1c792ce8e2fc342c0c63c2fab9c6fe-1805689@contact.gandi.net
issuer=/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
---
No client certificate CA names sent
---
SSL handshake has read 5848 bytes and written 328 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: A868799D47C550929ADF026FDC48CABD2444C96FDDAB86036196029BF7754D1B
Session-ID-ctx:
Master-Key: 6C0E428129970C6B1E358E134B12125373BED6FF50D55004A68A9042AD4E51C6D70BB8480266CC1BD1F11B093E212BFC
Key-Arg : None
Start Time: 1433943895
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
Trackobot.com:443 pour analyse-ssl:
-- trackobot.com port 443
! server sent unused chain certificate '/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority'
! server sent unused chain certificate '/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority'
* maximum SSL version : TLSv1_2 (SSLv23)
* supported SSL versions with handshake used and preferred cipher(s):
* handshake protocols ciphers
* SSLv23 TLSv1_2 ECDHE-RSA-AES256-GCM-SHA384
* TLSv1_2 TLSv1_2 ECDHE-RSA-AES256-GCM-SHA384
* TLSv1_1 TLSv1_1 ECDHE-RSA-AES256-SHA
* TLSv1 TLSv1 ECDHE-RSA-AES256-SHA
* SSLv3 FAILED: SSL connect attempt failed because of handshake problems error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
* cipher order by : server
* SNI supported : ok
* certificate verified : ok
* chain on 5.102.146.151
* [0/0] bits=2048, ocsp_uri=http://ocsp.startssl.com/sub/class1/server/ca, /C=CH/CN=www.trackobot.com/emailAddress=df1c792ce8e2fc342c0c63c2fab9c6fe-1805689@contact.gandi.net SAN=DNS:www.trackobot.com,DNS:trackobot.com
* [1/1] bits=2048, ocsp_uri=http://ocsp.startssl.com/ca, /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA
* [2/-] bits=4096, ocsp_uri=, /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
* [-/2] bits=4096, ocsp_uri=, /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
* OCSP stapling : no stapled response
* OCSP status : good (soft error: no ocsp_uri for /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority)
Versions:
Mac OSX 10.10.3
OpenSSL 0.9.8zd 8 Jan 2015
Java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
Quelqu'un peut-il repérer les échecs de mon programme Java? Que puis-je faire pour répondre aux exigences de négociation du serveur? Je ce vraiment la question?
Selon https://www.ssllabs.com , le serveur prend en charge les suites de chiffrement.
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ils sont répertoriés comme "suite de chiffrement indisponible", comme vous pouvez le constater dans les messages de débogage.
Dans JRE/lib/security/local_policy.jar, nous voyons
// Some countries have import limits on crypto strength. This policy file
// is worldwide importable.
grant {
permission javax.crypto.CryptoPermission "DES", 64;
permission javax.crypto.CryptoPermission "DESede", *;
permission javax.crypto.CryptoPermission "RC2", 128,
"javax.crypto.spec.RC2ParameterSpec", 128;
permission javax.crypto.CryptoPermission "RC4", 128;
permission javax.crypto.CryptoPermission "RC5", 128,
"javax.crypto.spec.RC5ParameterSpec", *, 12, *;
permission javax.crypto.CryptoPermission "RSA", *;
permission javax.crypto.CryptoPermission *, 128;
};
Téléchargez et installez "(JCE) fichiers de stratégie juridictionnelle de force illimitée" - http://www.Oracle.com/technetwork/Java/javase/downloads/jce8-download-2133166.html - et je peux confirmer que problème résolu. Le fichier Lisez-moi dit
En raison des restrictions imposées par certains pays sur le contrôle des importations, la version de les fichiers de règles JCE regroupés dans Java Runtime Environment, ou JRE (TM), 8 environnement permettent une cryptographie "forte" mais limitée.. utilisé. Ce package de téléchargement (comprenant ce fichier README) fournit des fichiers de politique "de force illimitée" qui ne contiennent pas restrictions sur les forces de cryptographie.
Suites de chiffrement: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ...
Votre client Java ne propose aucune suite de chiffrement AES256.
Ignorer la suite de chiffrement indisponible: TLS_RSA_WITH_AES_256_CBC_SHA
Parce qu'ils ne sont pas disponibles dans votre application. Je ne suis pas un expert en Java, mais ces derniers ne sont pas disponibles dans votre Java ou doivent être explicitement activés. Ils sont nécessaires car le serveur ne prend en charge que les chiffrements AES256:
$ Perl analyze-ssl.pl -v3 --all-ciphers trackobot.com
...
* supported ciphers with SSLv23 handshake
* TLSv1_2 ECDHE-RSA-AES256-GCM-SHA384
* TLSv1_2 ECDHE-RSA-AES256-SHA384
* TLSv1_2 ECDHE-RSA-AES256-SHA
* TLSv1_2 DHE-RSA-AES256-GCM-SHA384
* TLSv1_2 DHE-RSA-AES256-SHA256
* TLSv1_2 DHE-RSA-AES256-SHA
Il est possible que la version de Java que vous utilisez ne prenne pas en charge AES256 en raison de réglementations en matière d'exportation. Voir https://knowledge.safe.com/articles/Error_Unexpected_Behavior/Enabling-AES256-in-the-Java-Runtime-Environment -for-Single-Sign-On
Grâce au conseil de Steffen Ullrich, j'ai vérifié les chiffrements dont Java disposait. Apparemment, en Java 8, vos chiffrements n’ont pas une force illimitée. Par exemple, dans mon cas, mon programme ne pouvait pas utiliser le chiffrement AES 256 bits requis par le serveur.
Pour résoudre ce problème, Oracle fournit un ensemble de fichiers de règles permettant un chiffrement de force illimité. Vous pouvez le trouver ici .
Le README indique:
En raison des restrictions imposées par certains pays sur le contrôle des importations, la version de les fichiers de règles JCE regroupés dans Java Runtime Environment, ou JRE (TM), 8 environnement permettent une cryptographie "forte" mais limitée à être utilisé.
Il suffit de télécharger le kit et de remplacer les fichiers appropriés comme indiqué dans les instructions d'installation. Après que j'ai fait cela, la poignée de main a fonctionné comme un charme.
Vous avez probablement besoin de mettre à jour votre JDK, nous avons eu un problème similaire sur notre serveur linux. Nous avons essayé différentes approches. Rien ne semblait fonctionner, y compris l'installation d'une nouvelle JCE.
Il existe un bogue dans le JDK concernant la connexion SSL HostnameVerifier qui désactive l’extension SNI, ce qui entraîne un échec de la négociation: http://www.Oracle.com/technetwork/Java/javase/2col/8u141-bugfixes-3720387.html .
Nous avons mis à jour le dernier jdk 8u162, tout est beau maintenant.