Il fallimento della stretta di mano potrebbe essersi verificato per vari motivi:
- Suite di cifratura incompatibili utilizzate dal client e dal server. Ciò richiederebbe al client di utilizzare (o abilitare) una suite di crittografia supportata dal server.
- Versioni incompatibili di SSL in uso (il server potrebbe accettare solo TLS v1, mentre il client è in grado di utilizzare solo SSL v3). Ancora una volta, il client potrebbe dover assicurarsi di utilizzare una versione compatibile del protocollo SSL / TLS.
- Percorso di trust incompleto per il certificato del server; il certificato del server probabilmente non è considerato attendibile dal client. Ciò comporterebbe generalmente un errore più dettagliato, ma è del tutto possibile. Di solito la correzione consiste nell'importare il certificato CA del server nel truststore del client.
- Il certificato viene rilasciato per un dominio diverso. Ancora una volta, ciò avrebbe comportato un messaggio più dettagliato, ma indicherò la correzione qui nel caso in cui questa sia la causa. La risoluzione in questo caso sarebbe ottenere il server (non sembra essere tuo) per utilizzare il certificato corretto.
Poiché l'errore sottostante non può essere individuato, è meglio attivare il -Djavax.net.debug=all
flag per abilitare il debug della connessione SSL stabilita. Con il debug attivato, è possibile individuare quale attività nell'handshake non è riuscita.
Aggiornare
Sulla base dei dettagli ora disponibili, sembra che il problema sia dovuto a un percorso di affidabilità del certificato incompleto tra il certificato emesso sul server e una CA principale. Nella maggior parte dei casi, ciò è dovuto al fatto che il certificato della CA principale è assente nel truststore, portando alla situazione in cui non può esistere un percorso sicuro del certificato; il certificato non è sostanzialmente attendibile dal client. I browser possono presentare un avviso in modo che gli utenti possano ignorarlo, ma lo stesso non è il caso dei client SSL (come la classe HttpsURLConnection o qualsiasi libreria client HTTP come Apache HttpComponents Client ).
La maggior parte di queste classi / librerie client farebbe affidamento sull'archivio di fiducia utilizzato da JVM per la convalida del certificato. Nella maggior parte dei casi, questo sarà il cacerts
file nella directory JRE_HOME / lib / security. Se il percorso del truststore è stato specificato utilizzando la proprietà di sistema JVM javax.net.ssl.trustStore
, l'archivio in quel percorso è in genere quello utilizzato dalla libreria client. In caso di dubbi, dai un'occhiata alla tua Merchant
classe e scopri la classe / libreria che sta utilizzando per stabilire la connessione.
L'aggiunta del certificato del server che emette CA a questo truststore dovrebbe risolvere il problema. È possibile fare riferimento alla mia risposta su una domanda correlata su come ottenere strumenti per questo scopo, ma l' utilità keytool Java è sufficiente per questo scopo.
Avviso : l'archivio sicuro è essenzialmente l'elenco di tutte le autorità di certificazione di cui ti fidi. Se si inserisce un certificato che non appartiene a una CA di cui non ci si fida, le connessioni SSL / TLS a siti con certificati emessi da tale entità possono essere decodificate se la chiave privata è disponibile.
Aggiornamento n. 2: comprensione dell'output della traccia JSSE
Il keystore e i truststor usati dalla JVM sono di solito elencati all'inizio, un po 'come i seguenti:
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 :
Se viene utilizzato il truststore errato, sarà necessario reimportare il certificato del server in quello corretto o riconfigurare il server per utilizzare quello elencato (non consigliato se si dispone di più JVM e tutti vengono utilizzati per diversi esigenze).
Se si desidera verificare se l'elenco di certificati attendibili contiene i certificati richiesti, esiste una sezione per lo stesso, che inizia come:
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
Dovrai cercare se la CA del server è un argomento.
Il processo di handshake avrà alcune voci salienti (sarà necessario conoscere SSL per capirle in dettaglio, ma ai fini del debug del problema corrente, sarà sufficiente sapere che un server handshake_failure è generalmente riportato in ServerHello.
1. ClientHello
Una serie di voci verrà segnalata durante l'inizializzazione della connessione. Il primo messaggio inviato dal client in una configurazione di connessione SSL / TLS è il messaggio ClientHello, generalmente riportato nei registri come:
*** 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 }
***
Nota le suite di crittografia utilizzate. Ciò potrebbe dover concordare con la voce nel file merchant.properties, poiché la stessa convenzione potrebbe essere utilizzata dalla biblioteca della banca. Se la convenzione utilizzata è diversa, non c'è motivo di preoccuparsi, poiché ServerHello lo dichiarerà, se la suite di crittografia è incompatibile.
2. ServerHello
Il server risponde con un ServerHello, che indicherà se la configurazione della connessione può procedere. Le voci nei registri sono in genere del seguente tipo:
*** ServerHello, TLSv1
RandomCookie: GMT: 1291302499 bytes = { some byte array}
Cipher Suite: SSL_RSA_WITH_RC4_128_SHA
Compression Method: 0
***
Nota la suite di crittografia che ha scelto; questa è la migliore suite disponibile sia per il server che per il client. Di solito la suite di crittografia non viene specificata in caso di errore. Il certificato del server (e facoltativamente l'intera catena) viene inviato dal server e verrà trovato nelle voci come:
*** 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
***
Se la verifica del certificato ha avuto esito positivo, troverai una voce simile a:
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
Uno dei passaggi precedenti non avrebbe avuto esito positivo, risultante in handshake_failure, poiché l'handshake è in genere completa in questa fase (non proprio, ma le fasi successive dell'handshake in genere non causano un fallimento della stretta di mano). Dovrai capire quale passaggio ha avuto esito negativo e pubblicare il messaggio appropriato come aggiornamento alla domanda (a meno che tu non abbia già compreso il messaggio e tu sappia cosa fare per risolverlo).