L'échec de la poignée de main peut s'être produit pour diverses raisons:
- Suites de chiffrement incompatibles utilisées par le client et le serveur. Cela nécessiterait que le client utilise (ou active) une suite de chiffrement prise en charge par le serveur.
- Versions incompatibles de SSL en cours d'utilisation (le serveur peut n'accepter que TLS v1, tandis que le client ne peut utiliser que SSL v3). Encore une fois, le client devra peut-être s'assurer qu'il utilise une version compatible du protocole SSL / TLS.
- Chemin de confiance incomplet pour le certificat de serveur; le certificat du serveur n'est probablement pas approuvé par le client. Cela entraînerait généralement une erreur plus verbeuse, mais c'est tout à fait possible. Habituellement, le correctif consiste à importer le certificat CA du serveur dans le magasin de confiance du client.
- Le certificat est délivré pour un domaine différent. Encore une fois, cela aurait abouti à un message plus détaillé, mais je vais indiquer le correctif ici au cas où cela serait la cause. La résolution dans ce cas serait de demander au serveur (il ne semble pas être le vôtre) d'utiliser le bon certificat.
É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 JVM javax.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 à votre Merchant
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:
keyStore is :
keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
trustStore is: C:\Java\jdk1.6.0_21\jre\lib\security\cacerts
trustStore type is : jks
trustStore provider is :
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:
adding as trusted cert:
Subject: CN=blah, O=blah, C=blah
Issuer: CN=biggerblah, O=biggerblah, C=biggerblah
Algorithm: RSA; Serial number: yadda
Valid from SomeDate until SomeDate
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:
*** ClientHello, TLSv1
RandomCookie: GMT: 1291302508 bytes = { some byte array }
Session ID: {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods: { 0 }
***
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:
*** ServerHello, TLSv1
RandomCookie: GMT: 1291302499 bytes = { some byte array}
Cipher Suite: SSL_RSA_WITH_RC4_128_SHA
Compression Method: 0
***
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:
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=server, O=server's org, L=server's location, ST =Server's state, C=Server's country
Signature Algorithm: SHA1withRSA, OID = some identifer
.... the rest of the certificate
***
Si la vérification du certificat a réussi, vous trouverez une entrée similaire à:
Found trusted certificate:
[
[
Version: V1
Subject: OU=Server's CA, O="Server's CA's company name", C=CA's country
Signature Algorithm: SHA1withRSA, OID = some identifier
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).