J'ai un problème avec la connexion SSL autorisée. J'ai créé Struts Action qui se connecte au serveur externe avec un certificat SSL autorisé par le client. Dans mon action, j'essaie d'envoyer des données au serveur de la banque mais sans aucune chance, car j'ai à la suite du serveur l'erreur suivante:
error: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Ma méthode de ma classe Action qui envoie des données au serveur
//Getting external IP from host
URL whatismyip = new URL("http://automation.whatismyip.com/n09230945.asp");
BufferedReader inIP = new BufferedReader(new InputStreamReader(whatismyip.openStream()));
String IPStr = inIP.readLine(); //IP as a String
Merchant merchant;
System.out.println("amount: " + amount + ", currency: " + currency + ", clientIp: " + IPStr + ", description: " + description);
try {
merchant = new Merchant(context.getRealPath("/") + "merchant.properties");
} catch (ConfigurationException e) {
Logger.getLogger(HomeAction.class.getName()).log(Level.INFO, "message", e);
System.err.println("error: " + e.getMessage());
return ERROR;
}
String result = merchant.sendTransData(amount, currency, IPStr, description);
System.out.println("result: " + result);
return SUCCESS;
Mon fichier merchant.properties:
bank.server.url=https://-servernameandport-/
https.cipher=-cipher-
keystore.file=-key-.jks
keystore.type=JKS
keystore.password=-password-
ecomm.server.version=2.0
encoding.source=UTF-8
encoding.native=UTF-8
Pour la première fois, j'ai pensé qu'il s'agissait d'un problème de certificat, je l'ai converti de .pfx en .jks, mais j'ai la même erreur, sans changement.
Réponses:
L'échec de la poignée de main peut s'être produit pour diverses raisons:
Étant donné que l'échec sous-jacent ne peut pas être identifié, il est préférable d'activer l'
-Djavax.net.debug=all
indicateur pour activer le débogage de la connexion SSL établie. Avec le débogage activé, vous pouvez identifier quelle activité de la poignée de main a échoué.Mettre à jour
Sur la base des détails désormais disponibles, il semble que le problème soit dû à un chemin d'accès de confiance de certificat incomplet entre le certificat émis vers le serveur et une autorité de certification racine. Dans la plupart des cas, cela est dû au fait que le certificat de l'autorité de certification racine est absent du magasin de confiance, ce qui conduit à la situation dans laquelle un chemin de confiance de certificat ne peut pas exister; le certificat n'est essentiellement pas approuvé par le client. Les navigateurs peuvent présenter un avertissement afin que les utilisateurs puissent l'ignorer, mais il n'en est pas de même pour les clients SSL (comme la classe HttpsURLConnection , ou toute bibliothèque client HTTP comme Apache HttpComponents Client ).
La plupart de ces classes / bibliothèques clientes reposent sur le magasin de confiance utilisé par la machine virtuelle Java pour la validation des certificats. Dans la plupart des cas, ce sera le
cacerts
fichier dans le répertoire JRE_HOME / lib / security. Si l'emplacement du magasin de confiance a été spécifié à l'aide de la propriété système JVMjavax.net.ssl.trustStore
, le magasin de ce chemin est généralement celui utilisé par la bibliothèque cliente. En cas de doute, jetez un œil à votreMerchant
classe et déterminez la classe / bibliothèque qu'elle utilise pour établir la connexion.L'ajout du certificat du serveur émettant l'autorité de certification à ce magasin de confiance devrait résoudre le problème. Vous pouvez vous référer à ma réponse sur une question connexe sur l'obtention d'outils à cet effet, mais l' utilitaire Java keytool est suffisant à cet effet.
Avertissement : le magasin de confiance est essentiellement la liste de toutes les autorités de certification auxquelles vous faites confiance. Si vous insérez un certificat qui n'appartient pas à une autorité de certification à laquelle vous ne faites pas confiance, les connexions SSL / TLS aux sites disposant de certificats émis par cette entité peuvent être déchiffrées si la clé privée est disponible.
Mise à jour n ° 2: Comprendre la sortie de la trace JSSE
Le keystore et les truststores utilisés par la JVM sont généralement répertoriés au tout début, un peu comme suit:
Si le mauvais truststore est utilisé, vous devrez réimporter le certificat du serveur dans le bon, ou reconfigurer le serveur pour utiliser celui répertorié (non recommandé si vous avez plusieurs JVM, et tous sont utilisés pour différents Besoins).
Si vous souhaitez vérifier si la liste des certificats de confiance contient les certificats requis, il existe une section pour le même, qui commence par:
Vous devrez rechercher si l'autorité de certification du serveur est un sujet.
Le processus de prise de contact aura quelques entrées importantes (vous aurez besoin de connaître SSL pour les comprendre en détail, mais dans le but de déboguer le problème actuel, il suffira de savoir qu'un handshake_failure est généralement signalé dans ServerHello.
1. ClientHello
Une série d'entrées sera signalée lorsque la connexion est en cours d'initialisation. Le premier message envoyé par le client dans une configuration de connexion SSL / TLS est le message ClientHello, généralement signalé dans les journaux comme:
Notez les suites de chiffrement utilisées. Cela devra peut-être être conforme à l'entrée de votre fichier merchant.properties, car la même convention pourrait être utilisée par la bibliothèque de la banque. Si la convention utilisée est différente, il n'y a pas de raison de s'inquiéter, car ServerHello l'indiquera si la suite de chiffrement est incompatible.
2. ServerHello
Le serveur répond avec un ServerHello, qui indiquera si la configuration de la connexion peut se poursuivre. Les entrées dans les journaux sont généralement du type suivant:
Notez la suite de chiffrement qu'il a choisie; c'est la meilleure suite disponible pour le serveur et le client. En général, la suite de chiffrement n'est pas spécifiée en cas d'erreur. Le certificat du serveur (et éventuellement la chaîne entière) est envoyé par le serveur, et se trouverait dans les entrées sous la forme:
Si la vérification du certificat a réussi, vous trouverez une entrée similaire à:
L'une des étapes ci-dessus n'aurait pas réussi, ce qui aurait abouti à handshake_failure, car la prise de contact est généralement terminée à ce stade (pas vraiment, mais les étapes suivantes de la prise de contact ne provoquent généralement pas d'échec de la prise de contact). Vous devrez déterminer quelle étape a échoué et publier le message approprié en tant que mise à jour de la question (sauf si vous avez déjà compris le message et que vous savez quoi faire pour le résoudre).
la source
keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts
commande pour imprimer le contenu. Vérifiez ensuite si les certificats dans cacerts correspondent à l'autorité de certification du certificat de la banque.changeit
. À moins que cela ne soit changé.L'installation de Java Cryptography Extension (JCE) Unlimited Strength ( pour JDK7 | pour JDK8 ) peut résoudre ce bogue. Décompressez le fichier et suivez le readme pour l'installer.
la source
L'échec de la négociation peut être une implémentation du protocole TLSv1 boguée.
Dans notre cas, cela a aidé avec java 7:
Le jvm négociera dans cet ordre. Les serveurs avec la dernière mise à jour feront 1.2, les bogués passeront à la v1 et cela fonctionne avec la v1 similaire en java 7.
la source
Cela peut également se produire lorsque le client doit présenter un certificat. Une fois que le serveur a répertorié la chaîne de certificats, les événements suivants peuvent se produire:
3. Demande de certificat Le serveur émettra une demande de certificat à partir du client. La demande listera tous les certificats acceptés par le serveur.
4. Chaîne de certificat client Il s'agit du certificat que le client envoie au serveur.
S'il n'y a pas de certificat dans la chaîne et que le serveur en a besoin, vous obtiendrez l'erreur d'établissement de liaison ici. Une cause probable est que le chemin d'accès à votre certificat n'a pas été trouvé.
5. Vérification du certificat Le client demande au serveur de vérifier le certificat
Cette étape ne se produira que si vous envoyez un certificat.
6. Terminé Le serveur répondra avec une réponse de vérification
la source
Je ne pense pas que cela résout le problème du premier interrogateur, mais pour les googleurs qui viennent ici pour obtenir des réponses:
Sur la mise à jour 51, java 1.8 interdisait [1] les chiffrements RC4 par défaut, comme nous pouvons le voir sur la page Notes de publication:
Si votre serveur a une forte préférence pour ce chiffrement (ou n'utilise que ce chiffrement), cela peut déclencher un
handshake_failure
sur java.Vous pouvez tester la connexion au serveur en activant les chiffrements RC4 (d'abord, essayez sans
enabled
argument pour voir si le déclencheur ahandshake_failure
, puis définissezenabled
:1 - https://www.java.com/en/download/faq/release_changes.xml
la source
J'ai cette erreur pendant que j'essayais d'utiliser JDK 1.7. Lorsque j'ai mis à niveau mon JDK vers jdk1.8.0_66, tout a commencé à fonctionner correctement.
La solution la plus simple à ce problème pourrait donc être: mettez à niveau votre JDK et cela pourrait commencer à bien fonctionner.
la source
Dans mon cas, le certificat est importé, l'erreur persiste, résolu cela en ajoutant
System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");
avant de se connecterla source
En supposant que vous utilisez les protocoles SSL / TLS appropriés, que vous avez correctement configuré votre
keyStore
et que vous aveztrustStore
confirmé qu'il n'y a aucun problème avec les certificats eux-mêmes, vous devrez peut-être renforcer vos algorithmes de sécurité .Comme mentionné dans la réponse de Vineet , l'une des raisons possibles pour lesquelles vous recevez cette erreur est due à l'utilisation de suites de chiffrement incompatibles. En mettant à jour mes
local_policy
etUS_export_policy
jars dans lesecurity
dossier de mon JDK avec ceux fournis dans l' extension de cryptographie Java (JCE) , j'ai pu terminer la négociation avec succès.la source
Je rencontre le même problème aujourd'hui avec le client OkHttp pour OBTENIR une URL basée sur https. Cela était dû à la version du protocole Https et à l'incompatibilité de la méthode de chiffrement entre le côté serveur et le côté client .
1) Vérifiez la version du protocole https et la méthode de chiffrement de votre site Web.openssl>s_client -connect your_website.com:443 -showcerts
Vous obtiendrez de nombreuses informations détaillées, les informations clés sont répertoriées comme suit:
2) configurez votre client http, par exemple, dans le cas du client OkHttp :Cela obtiendra ce que nous voulons.
la source
J'ai trouvé un serveur HTTPS qui a échoué de cette manière si mon processus client Java était configuré avec
La connexion a échoué avec une
handshake_failure
fois que leServerHello
s'est terminé avec succès mais avant le démarrage du flux de données.Il n'y avait pas de message d'erreur clair identifiant le problème, l'erreur ressemblait simplement à
J'ai isolé le problème en essayant avec et sans l'
-Djsse.enableSNIExtension=false
option " "la source
Le mien était une
TLS
erreur incompatible avec la version.Auparavant,
TLSv1
je l'ai changé,TLSV1.2
cela a résolu mon problème.la source
J'utilise le client http com.google.api. Lorsque je communique avec un site d'entreprise interne, j'ai ce problème lorsque j'ai utilisé par erreur https au lieu de http.
la source
J'ai eu un problème similaire; la mise à niveau vers Apache HTTPClient 4.5.3 l'a corrigé.
la source
Ugg! Cela s'est avéré être simplement un problème de version Java pour moi. J'ai eu l'erreur de poignée de main en utilisant JRE 1.6 et tout fonctionnait parfaitement avec JRE 1.8.0_144.
la source
Avis de non-responsabilité: je ne sais pas si la réponse sera utile pour de nombreuses personnes, partageant simplement parce que cela pourrait.
J'obtenais cette erreur en utilisant Parasoft SOATest pour envoyer une requête XML (SOAP).
Le problème était que j'avais sélectionné le mauvais alias dans la liste déroulante après avoir ajouté le certificat et l'avoir authentifié.
la source
Dans mon cas, le site Web peut simplement utiliser TLSv1.2. et j'utilise apache httpclient 4.5.6, j'utilise ce code et j'installe jce pour résoudre ce problème (JDK1.7):
jce
jdk7 http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
jdk 8 http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
code:
la source
Pour dépanner du point de vue du développeur (élément 1) et de l'administrateur système (éléments 2 et 3):
-Djavax.net.debug=ssl:handshake:verbose
.sudo apt install ssldump
ou compilez à partir des sources en suivant ce lien si vous observezUnknown value
dans le chiffrement lorsque vous exécutez l'étape ci-dessous.sudo ssldump -k <your-private-key> -i <your-network-interface>
Exemple de non-fonctionnement de la négociation du journal ssldump:
Exemple de négociation réussie du journal ssldump
Exemple de journal Java qui ne fonctionne pas
la source
Dans mon cas, j'ai eu un problème avec la version 1.1. Je reproduisais facilement le problème avec curl. Le serveur ne prenait pas en charge les versions inférieures à TLS1.2.
Ce problème de prise de contact a été reçu:
Avec la version 1.2, cela fonctionnait bien:
Le serveur exécutait un Weblogic et l'ajout de cet argument dans setEnvDomain.sh l'a fait fonctionner avec TLSv1.1:
la source
Ce problème se produit à cause de la version java. J'utilisais 1.8.0.231 JDK et j'obtenais cette erreur. J'ai dégradé ma version java de 1.8.0.231 à 1.8.0.171, maintenant cela fonctionne bien.
la source