Quantcast
Channel: Antonio Musarra's Blog
Viewing all articles
Browse latest Browse all 38

Importazione Certificati SSL sul Java Keystore (JKS)

$
0
0

Importazione Certificati SSL sul Java Keystore (JKS)
Antonio Musarra's Blog

Il meccanismo solitamente adottato per la protezione dei dati End-To-End sulla rete internet è basato sull’utilizzo del protocollo Transport Layer Security (TLS) e il suo predecessore Secure Sockets Layer (SSL), entrambi sono dei protocolli crittografici che permettono una comunicazione sicura e una integrità dei dati su reti TCP/IP, cifrano la comunicazione dalla sorgente alla destinazione sul livello di trasporto.

Una tipica connessione TLS/SSL (per esempio via browser internet) prevede un tipo di autenticazione denominata unilaterale : solo il server è autenticato (il client conosce l’identità del server), ma non vice-versa (il client rimane anonimo e non autenticato). Il client (browser web, EmailUI, Java Client, etc…) valida il certificato del server controllando la firma digitale dei certificati del server, verificando che questa sia valida e riconosciuta da una Certificate Authority conosciuta utilizzando una cifratura a chiave pubblica.

In Figura 1 è illustrato il caso in cui il browser stabilisce una connessione verso un sito web (o applicazione web) che espone un certificato rilasciato da una Certificate Authority non riconosciuta. E’ lasciata all’utente l’azione da intraprendere, se continuare o abbandonare la connessione, è inoltre possibile per l’utente, istruire il browser affinché consideri trusty (fidato) il certificato.

Figura 1 - Alert del Browser per Certificate Authority non riconosciuta

Figura 1 - Alert del Browser per Certificate Authority non riconosciuta

In Figura 2 sono invece illustrati i dettagli sulla catena di certificazione (Certificate Chain). Il browser (in questo caso Safari) ha tutte la ragioni a emettere un warning, in effetti, la CA (Certificate Authority)  indicata è di pura invenzione.

Figura 2 - Dettagli del certificato SSL

Figura 2 - Dettagli del certificato SSL

Nel caso in cui volessimo compiere connessioni TLS/SSL attraverso un software scritto in Java (in qualità di client), è necessario accertarsi che tutta la Certificate Chain (o catena di certificazione) sia soddisfatta o comunque bisogna far in modo da considerare affidabile il certificato. La piattaforma Java utilizza un sistema denominato Java Keystore per la gestione della sicurezza o meglio, per lo storage e amministrazione di tutto ciò che ruota intorno ai certificati digitali (Public/Private Key, Root CA, CSR, etc…). L’implementazione di default del Java Keystore è basata su file, quest’ultimo è in un formato proprietario denominato JKS. Per coloro che volessero approfondire l’argomento sicurezza in Java, consiglio la lettura di JDK 6 Security-related APIs & Developer Guides.

La piattaforma Java prevede due tipi di Java Keystore che preferisco suddividere nel seguente modo:

  • Server side: Java Keystore che contiene solitamente le coppie di chiavi pubbliche/private dei certificati utilizzati dall’applicazione server. Il nome solitamente attribuito a questo repository è keystore;
  • Client side: Java Keystore che contiene i soli certificati utilizzati dalle applicazioni che agiscono come client. Il nome solitamente attribuito a questo repository è trustStore.

La locazione predefinita di entrambi i keystore è <java-home>/lib/security/. Per ragioni di semplicità, durante il corso dell’articolo farò riferimento in modo generico al nome keystore.

Il classico errore cui si va incontro quando la Certificate Chain non è soddisfatta, è un eccezione del tipo indicato di seguito. L’eccezione è scatena perché non è stata trovata una Certification Path valida per la richiesta di connessione SSL eseguita.

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target

Andiamo subito nel pratico e vediamo come affrontare uno scenario simile prendendo come esempio un recente articolo pubblicato sul mio blog, che mostrava come realizzare un client Java SOAP per il sistema di CRM SugarCRM. Gli esempi di connessione (mostrati nell’articolo) al servizio SOAP utilizzano il protocollo HTTP. Qualora facessimo uso del protocollo HTTPS per la connessione al servizio SOAP, andremmo incontro all’eccezione mostrata in precedenza. La soluzione al problema è molto semplice, occorre importare il certificato SSL sul proprio Java Keystore e segnarlo come affidabile. L’operazione è composta dai seguenti passi elementari:

  1. Esportazione/Salvataggio del certificato server in formato DER (Distinguished Encoding Rules) X.509 sulla propria macchina o su quella che eseguirà la connessione SSL;
  2. Importazione del certificato server sul Java Keystore.

L’esportazione del certificato server può essere eseguita in svariati modi, forse la via più semplice è attraverso un comune browser (Firefox, Internet Explore, Safari, etc…). Riporto il post che spiega come eseguire l’operazione con Mozilla Firefox: Exporting Server Certificate to File in Firefox 3. In modo analogo è possibile procedere con l’esportazione del certificato server utilizzando i più comuni browser.

Il metodo da me preferito per esportare il certificato server in formato DER è l’utilizzo del tool openssl. E’ più che sufficiente una sola linea di comando, per motivi di leggibilità, riporto il comando suddiviso in 4 linee:

echo |
openssl s_client -connect sugarcrm-fe-1.local:443 2&gt;&amp;1 |
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | 
openssl x509 -outform der -out /tmp/sugarcrm-fe-1.local.der

Una volta ottenuto il certificato server, occorre importare quest’ultimo sul Java Keystore utilizzando l’apposito tool che prende il nome di keytool (keytool-Key and Certificate Management Tool). Ricordo che il keystore è il contenitore dei certificati digitali. Ognuno di voi potrebbe avere le configurazioni più disparate riguardo il Java Keystore, lo scenario qui proposto è quello base, keystore su file e su file custom, ovvero, creato dall’importazione del certificato server, lasciamo intatto il keystore di sistema.

keytool -import -keystore /Users/amusarra/.mykeystore 
-alias sugarcrm-fe-1 -v -file Desktop/sugarcrm-fe-1.local

Il comando sopra illustrato, creerà un nuovo keystore (protetto da password) all’interno del quale finirà il certificato server identificato con l’alias sugarcrm-fe-1. L’alias identifica in modo univoco l’item appena inserito, se volessimo fare un controllo sul buon esito dell’operazione dell’import, è sufficiente eseguire il seguente comando:

keytool -list -keystore /Users/amusarra/.mykeystore 
-v -alias sugarcrm-fe-1

L’output del precedente comando sarà simile a quanto illustrato a seguire:

Alias name: sugarcrm-fe-1
Creation date: May 2, 2011
Entry type: trustedCertEntry

<strong>Owner</strong>: EMAILADDRESS=info@sugarcrm-fe-1.local, CN=sugarcrm-fe-1.local,
OU=Research Development, O=Shirus Labs Ltd, L=Rome, ST=Italy, C=IT
<strong>Issuer</strong>: EMAILADDRESS=info@shiruslabs.com, CN=www.shiruslabs.com,
OU=IT Systems, O=Shirus Labs Ltd, L=Rome, ST=Italy, C=IT
Serial number: 1
Valid from: Thu Apr 28 02:18:12 CEST 2011 until: Sun Apr 25 02:18:12 CEST 2021
Certificate fingerprints:
     MD5:  CC:4A:D4:6E:DC:01:60:1D:79:FA:CD:8A:46:5F:CC:48
     SHA1: A5:44:B9:C7:0A:41:0C:92:46:C6:9D:6D:77:0B:89:35:ED:E9:1C:AD
     Signature algorithm name: SHA1withRSA
     Version: 1

Nel caso in cui il certificato server non fosse stato importato con successo, il precedente comando avrebbe risposto con la seguente eccezione:

keytool error:
java.lang.Exception: Alias &lt;sugarcrm-fe&gt; does not exist
java.lang.Exception: Alias &lt;sugarcrm-fe&gt; does not exist
    at sun.security.tools.KeyTool.doPrintEntry(KeyTool.java:1339)
    at sun.security.tools.KeyTool.doCommands(KeyTool.java:869)
    at sun.security.tools.KeyTool.run(KeyTool.java:172)
    at sun.security.tools.KeyTool.main(KeyTool.java:166)

A questo punto tutto è pronto per poter eseguire con successo la connessione al servizio SOAP over HTTPS. Poiché abbiamo utilizzato un keystore custom invece di sfruttare quello di sistema, è necessario istruire la JVM circa il keystore da utilizzare, non sarebbe neppure una cattiva idea quella d’impostare un livello di debug sulla sola connessione SSL. I due argomenti che devono essere passati alla JVM sono quindi:

-Djavax.net.debug=ssl
-Djavax.net.ssl.trustStore=/Users/amusarra/.mykeystore

Dato che l’applicazione Java agisce in qualità di client, occorre specificare la locazione del keystore (che ricordo essere di tipo trustStore) attraverso la proprietà java.net.ssl.trustStore.

L’opzione di debug può aiutare a capire eventuali problemi in caso di malfunzionamento, è comuque utile per coloro che vogliono capire meglio il funzionamento del protocollo TLS/SSL, vengono tracciati tutti i messaggi scambiati tra il client ed il server per portare a termine la fase di handshake. A seguire un estratto dell’output a fronte dell’esecuzione della classe SugarCRMSoapClient.java, cambiando però l’indirizzo dell’endpoint in https://sugarcrm-fe-1.local/crm-6.1/service/v2/soap.php?wsdl

Attraverso un esempio pratico e direi pure abbastanza realistico, abbiamo visto come sia semplice e immediato importare certificati digitali sul Java Keystore affinché le applicazioni SSL funzionino in maniera corretta.

Credo che questo sia il mio terzo articolo nato per rispondere alle domande e/o problemi posti da miei colleghi!!!

keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
trustStore is: /Users/amusarra/.mykeystore
trustStore type is : jks
trustStore provider is :
init truststore
adding as trusted cert:
  Subject: EMAILADDRESS=info@sugarcrm-fe-1.local,
CN=sugarcrm-fe-1.local, OU=Research Development,
O=Shirus Labs Ltd, L=Rome, ST=Italy, C=IT
  Issuer:  EMAILADDRESS=info@shiruslabs.com, CN=www.shiruslabs.com,
OU=IT Systems, O=Shirus Labs Ltd, L=Rome, ST=Italy, C=IT
  Algorithm: RSA; Serial number: 0x1
  Valid from Thu Apr 28 02:18:12 CEST 2011 until Sun Apr 25 02:18:12 CEST 2021

trigger seeding of SecureRandom
done seeding SecureRandom

*** ClientHello, TLSv1
RandomCookie:  GMT: 1287446936 bytes = { 34, 19, 132, 181, 138, 114, 13,
67, 100, 111, 100, 155, 35, 132, 108, 102, 110, 106, 128, 57, 200, 147,
175, 25, 246, 233, 34, 252 }
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_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,
TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
***
Thread-2, WRITE: TLSv1 Handshake, length = 81
Thread-2, WRITE: SSLv2 client hello message, length = 110
Thread-2, READ: TLSv1 Handshake, length = 81
*** ServerHello, TLSv1
RandomCookie:  GMT: 1287126586 bytes = { 72, 54, 32, 71, 9, 157, 75, 184,
3, 159, 95, 8, 18, 248, 108, 249, 179, 60, 205, 184, 204, 135, 186, 220,
27, 85, 249, 234 }
Session ID:  {116, 147, 251, 240, 232, 125, 76, 210, 112, 151, 13,
181, 7, 214, 55, 176, 224, 217, 109, 201, 161, 74, 143, 121, 131,
243, 108, 67, 131, 234, 146, 232}
Cipher Suite: SSL_RSA_WITH_RC4_128_MD5
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: &lt;empty&gt;
***
%% Created:  [Session-1, SSL_RSA_WITH_RC4_128_MD5]
** SSL_RSA_WITH_RC4_128_MD5
Thread-2, READ: TLSv1 Handshake, length = 1484
*** Certificate chain
chain [0] = [
[
  Version: V1
  Subject: EMAILADDRESS=info@sugarcrm-fe-1.local, CN=sugarcrm-fe-1.local,
OU=Research Development, O=Shirus Labs Ltd, L=Rome, ST=Italy, C=IT
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 4096 bits
  modulus: 8027142309184580181165847677029426633214754078003759815426876
85293215600656132119778686073861448440626986882469379232984072851534463520
18325441288568133145387170109806353233631082021605339971510561262203242740
78307947239417239633029107273682201967984685272509448411609722527933446350
55918234578745856629515337728940982589703027293942988170613441271688911660
69762683263953403322683456690226470741799474704382776226873825494609402390
72693542287588215034771548006899103813169868373935038762384493733844944158
52659434703986779316888612522163711433463948775434712084653698002329763637
  public exponent: 65537
  Validity: [From: Thu Apr 28 02:18:12 CEST 2011,
               To: Sun Apr 25 02:18:12 CEST 2021]
  Issuer: EMAILADDRESS=info@shiruslabs.com, CN=www.shiruslabs.com,
OU=IT Systems, O=Shirus Labs Ltd, L=Rome, ST=Italy, C=IT
  SerialNumber: [    01]

]

The post Importazione Certificati SSL sul Java Keystore (JKS) appeared first on Antonio Musarra's Blog
Antonio Musarra's Blog - The ideal solution for a problem


Viewing all articles
Browse latest Browse all 38

Latest Images

Trending Articles





Latest Images