Der Handshake-Fehler kann verschiedene Ursachen haben:
- Inkompatible Cipher Suites, die vom Client und vom Server verwendet werden. Dies würde erfordern, dass der Client eine vom Server unterstützte Verschlüsselungssuite verwendet (oder aktiviert).
- Inkompatible Versionen von SSL werden verwendet (der Server akzeptiert möglicherweise nur TLS v1, während der Client nur SSL v3 verwenden kann). Auch hier muss der Client möglicherweise sicherstellen, dass er eine kompatible Version des SSL / TLS-Protokolls verwendet.
- Unvollständiger Vertrauenspfad für das Serverzertifikat; Das Zertifikat des Servers wird vom Client wahrscheinlich nicht als vertrauenswürdig eingestuft. Dies würde normalerweise zu einem ausführlicheren Fehler führen, ist aber durchaus möglich. Normalerweise besteht das Update darin, das CA-Zertifikat des Servers in den Trust Store des Clients zu importieren.
- Das Zertifikat wird für eine andere Domain ausgestellt. Auch dies hätte zu einer ausführlicheren Meldung geführt, aber ich werde das Update hier angeben, falls dies die Ursache ist. Die Lösung in diesem Fall wäre, den Server (es scheint nicht Ihr Server zu sein) dazu zu bringen, das richtige Zertifikat zu verwenden.
Da der zugrunde liegende Fehler nicht lokalisiert werden kann, ist es besser, das -Djavax.net.debug=all
Flag einzuschalten, um das Debuggen der hergestellten SSL-Verbindung zu ermöglichen. Bei eingeschaltetem Debug können Sie feststellen, welche Aktivität im Handshake fehlgeschlagen ist.
Aktualisieren
Basierend auf den jetzt verfügbaren Details scheint das Problem auf einen unvollständigen Zertifikatvertrauenspfad zwischen dem an den Server ausgestellten Zertifikat und einer Stammzertifizierungsstelle zurückzuführen zu sein. In den meisten Fällen liegt dies daran, dass das Zertifikat der Stammzertifizierungsstelle im Vertrauensspeicher nicht vorhanden ist, was dazu führt, dass kein Zertifikatvertrauenspfad vorhanden sein kann. Das Zertifikat ist vom Kunden im Wesentlichen nicht vertrauenswürdig. Browser können eine Warnung anzeigen , damit Benutzer dies ignorieren können. Dies gilt jedoch nicht für SSL-Clients (wie die HttpsURLConnection- Klasse oder eine HTTP-Client-Bibliothek wie Apache HttpComponents Client ).
Die meisten dieser Clientklassen / -bibliotheken würden sich auf den Vertrauensspeicher stützen, der von der JVM für die Zertifikatvalidierung verwendet wird. In den meisten Fällen ist dies die cacerts
Datei im Verzeichnis JRE_HOME / lib / security. Wenn der Speicherort des Vertrauensspeichers mithilfe der JVM-Systemeigenschaft angegeben wurde javax.net.ssl.trustStore
, wird der Speicher in diesem Pfad normalerweise von der Clientbibliothek verwendet. Wenn Sie Zweifel haben, schauen Sie sich Ihre Merchant
Klasse an und finden Sie heraus, mit welcher Klasse / Bibliothek die Verbindung hergestellt wird.
Durch Hinzufügen der Zertifikatzertifizierungsstelle des Servers zu diesem Vertrauensspeicher sollte das Problem behoben werden. Sie können sich auf meine Antwort zu einer verwandten Frage zum Abrufen von Tools für diesen Zweck beziehen , aber das Java-Dienstprogramm keytool ist für diesen Zweck ausreichend.
Warnung : Der Trust Store ist im Wesentlichen die Liste aller CAs, denen Sie vertrauen. Wenn Sie ein Zertifikat eingeben, das nicht zu einer Zertifizierungsstelle gehört, der Sie nicht vertrauen, können SSL / TLS-Verbindungen zu Sites mit von dieser Entität ausgestellten Zertifikaten entschlüsselt werden, wenn der private Schlüssel verfügbar ist.
Update Nr. 2: Grundlegendes zur Ausgabe des JSSE-Trace
Der Keystore und die von der JVM verwendeten Truststores werden normalerweise ganz am Anfang aufgelistet, ähnlich wie folgt:
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 :
Wenn der falsche Truststore verwendet wird, müssen Sie das Serverzertifikat erneut in das richtige Zertifikat importieren oder den Server für die Verwendung des aufgelisteten Zertifikats neu konfigurieren (nicht empfohlen, wenn Sie mehrere JVMs haben und alle für unterschiedliche verwendet werden Bedürfnisse).
Wenn Sie überprüfen möchten, ob die Liste der Vertrauenszertifikate die erforderlichen Zertifikate enthält, gibt es einen Abschnitt dafür, der wie folgt beginnt:
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
Sie müssen suchen, ob die Zertifizierungsstelle des Servers ein Thema ist.
Der Handshake-Prozess enthält einige wichtige Einträge (Sie müssen SSL kennen, um sie im Detail zu verstehen. Zum Debuggen des aktuellen Problems reicht es jedoch aus zu wissen, dass ein handshake_failure normalerweise im ServerHello gemeldet wird.
1. ClientHallo
Eine Reihe von Einträgen wird gemeldet, wenn die Verbindung initialisiert wird. Die erste vom Client in einem SSL / TLS-Verbindungsaufbau gesendete Nachricht ist die ClientHello-Nachricht, die normalerweise in den Protokollen wie folgt gemeldet wird:
*** 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 }
***
Beachten Sie die verwendeten Cipher Suites. Dies muss möglicherweise mit dem Eintrag in Ihrer Merchant.properties-Datei übereinstimmen , da dieselbe Konvention möglicherweise von der Bibliothek der Bank verwendet wird. Wenn die verwendete Konvention anders ist, besteht kein Grund zur Sorge, da ServerHello dies angibt, wenn die Verschlüsselungssuite nicht kompatibel ist.
2. ServerHallo
Der Server antwortet mit einem ServerHello, das angibt, ob der Verbindungsaufbau fortgesetzt werden kann. Einträge in den Protokollen sind normalerweise vom folgenden Typ:
*** ServerHello, TLSv1
RandomCookie: GMT: 1291302499 bytes = { some byte array}
Cipher Suite: SSL_RSA_WITH_RC4_128_SHA
Compression Method: 0
***
Beachten Sie die ausgewählte Chiffresuite. Dies ist die beste Suite, die sowohl dem Server als auch dem Client zur Verfügung steht. Normalerweise wird die Verschlüsselungssuite nicht angegeben, wenn ein Fehler auftritt. Das Zertifikat des Servers (und optional der gesamten Kette) wird vom Server gesendet und befindet sich in den Einträgen wie folgt:
*** 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
***
Wenn die Überprüfung des Zertifikats erfolgreich war, finden Sie einen Eintrag ähnlich dem folgenden:
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
Einer der oben genannten Schritte wäre nicht erfolgreich gewesen, was zu einem Handshake-Fehler geführt hätte, da der Handshake in dieser Phase normalerweise abgeschlossen ist (nicht wirklich, aber die nachfolgenden Phasen des Handshakes verursachen normalerweise keinen Handshake-Fehler). Sie müssen herausfinden, welcher Schritt fehlgeschlagen ist, und die entsprechende Nachricht als Aktualisierung der Frage veröffentlichen (es sei denn, Sie haben die Nachricht bereits verstanden und wissen, wie Sie sie beheben können).