A livello trasporto è possibile usare diversi protocolli di sicurezza, il più diffuso è SSL (Secure Socket Layer) con relative evoluzioni come TLS (Transport Layer Security). Le caratteristiche offerte dal protocollo forniscono:
Campo | Descrizione |
---|---|
Autenticazione | La comunicazione avviene tra attori fidati. |
Confidenzialità | I messaggi sono criptati. |
Integrità | I messaggi giungono non corrotti. |
Scambio sicuro di chiavi | Metodo crittografico. |
Sono quindi possibili tre modi d’uso:
Modalità | Descrizione |
---|---|
Nessuna autenticazione | Non viene adottato alcun certificato e si instaura solo la confidenzialità. |
Autenticazione a una via | Detta anche autenticazione del server. Ad autenticarsi, e conseguentemente ad esporre un certificato, è il solo server, che invia al client il certificato, client che a sua volta ne verifica le credenziali. E’ l’approccio tipicamente utilizzato nelle transazioni su Internet, ad esempio quelle bancarie. |
Autenticazione a due vie | O autenticazione bilaterale. Sia il server che il client si autenticano inviando il certificato. E’ un approccio che richiede maggiori tempi di elaborazione quindi più lento, ma necessario in particolare per prevenire minacce che possono venire dalla presenza di un proxy tra Web service e client. |
SSL lavora con una combinazione di chiavi segrete e pubbliche per instaurare una comunicazione sicura. La chiave segreta è utilizzata per criptare e decriptare il traffico, mentre la chiave pubblica è utilizzata per la mutua autenticazione delle parti coinvolte. In Java, la libreria nativa Java JSSE (Java Secure Socket Extension) si occupa di implementare il protocollo SSL/TLS, per cui l’implementazione della sicurezza a livello trasporto diventa un problema di configurazione di properties.
Certificati SSL, chiavi di sicurezza e X509
I certificati SSL sono files dati che consentono di associare una chiave di criptografia a un’organizzazione. Permettono di instaurare comunicazioni sicure e in genere accoppiano alla chiave un nome di dominio (nome di un server o un host) e l’identità di un’organizzazione (ad esempio nome di una compagnia e posizione). Stabilito il certificato, è possibile connettersi a un sito Web o a un Web service della compagnia tramite HTTPS.
Per avere piena validità ed essere considerati affidabili, i certificati dovrebbero essere rilasciati da un’autorità di certificazione. In questo capitolo e nel prossimo i certificati verranno creati in modalità self-signed, ossia realizzati e firmati dalla stessa entità che li utilizza. Questo approccio non è il massimo in termini di sicurezza e non fornisce elevate garanzie agli utilizzatori dei servizi, ma talvolta è utilizzato anche all’esterno del contesto di sviluppo e testing in quanto presenta costi nettamente inferiori rispetto a un certificato rilasciato dalle autorità. In primo luogo, questi certificati hanno un costo che arriva anche a migliaia di euro/anno. Vi sono diversi tools, anche nativi Java (keytool) e altri Open Source come OpenSSL, che consentono di creare i certificati senza costi aggiuntivi.
Inoltre, utilizzando questi tool è semplice customizzare i certificati in base alle esigenze (chiavi più o meno robuste, metadati..). Nella prossima lezione approfondiremo keytool e OpenSSL in modo da prepararci a creare certificati da utilizzare per instaurare sicurezza a livello trasporto.
Il sistema di criptografia a chiave segreta si basa su una chiave utilizzata sia per criptare che per decriptare. Poiché deve essere presente sia a destinazione che all’origine, un simile sistema richiede l’instaurazione di un canale sicuro per condividere la chiave.
Il sistema di criptografia a chiave pubblica si basa su di una coppia di chiavi, pubblica e privata, che usate in coppia consentono comunicazioni sicure anche senza bisogno di instaurare canali sicuri di scambio delle chiavi. Volendo infatti inviare un messaggio, sarà sufficiente conoscere la chiave pubblica del destinatario e criptare il messaggio con questa chiave. Per decriptare il destinatario utilizzerà la chiave privata. Ecco perché la chiave pubblica è definita tale, è possibile infatti renderla di dominio pubblico e quindi scambiarla sui normali canali non sicuri, non necessitando di un ulteriore protocollo di sicurezza per scambiare le chiavi. Il risvolto della medaglia è che in questo caso le procedure di criptazione e decriptazione sono più complesse e pesanti per la CPU. E' inoltre da considerare che in un ambiente di tipo publish/subscribe, con diversi utenti sottoscrittori interessati a ricevere dati mantenendo chiavi esclusive, la gestione tende a complicarsi.
L’X.509 è uno standard ITU-T (International Telecommunication Union - Telecommunication Standardization Sector) per infrastrutture a chiave pubblica (PKI), parte integrante dello standard X.500 per i servizi di directory (detti anche pagine bianche), una soluzione al problema dell’identificazione del possessore di una chiave crittografica. Attualmente alla versione V3, è basato su un sistema gerarchico di autorità di certificazione (CA). Una CA rilascia un certificato che accoppia una chiave pubblica a un nome distintivo o alternativo, ad esempio un’e-mail o un record DNS (Domain Name System). Una catena di certificati è una lista di certificati seguiti da uno o più certificati di autorità usati per assicurarsi che la chiave pubblica contenuta in un dato certificato e gli altri dati appartengono realmente a un soggetto. I certificati presentano una serie di informazioni tra le quali troviamo versione, ente emittente, validità, soggetto, oltre all’algoritmo di firma del certificato e la firma.
Keystore e truststore
La gestione del canale di comunicazione sicuro viene affidata a JSSE e risulta trasparente tanto agli utilizzatori quanto agli sviluppatori, in quanto il tutto si traduce con una serie di properties da settare. Dal punto vi vista delle applicazioni, ciò significa indicare dove è possibile trovare i certificati lato server e lato client. In base al tipo di autenticazione scelta si provvederà a dotare una o tutte e due le parti di certificati emessi in proprio o da un’autorità di certificazione. Per indicare la posizione dei certificati è possibile agire in modo programmatico, con un impatto sul codice minimale ma presente, o con ancora minore impatto agendo sui parametri di lancio, evitando così del tutto di dover mettere mano a un codice che magari non si può modificare.
Il keystore è un archivio per certificati di sicurezza e chiavi private. In Java JKS è l’estensione default per i keystore. I keystores sono utilizzati dalla classe Java KeyManager
che stabilisce quali credenziali d’autorizzazione inviare all’host remoto per eseguire l’autenticazione nell’handshake SSL. Keytool è un tool presente nella SE con il quale è possibile manipolare un keystore in formato JKS, ma non offre alcune funzionalità utili come l’estrazione/importazione della chiave privata. In alcuni casi, potrebbero essere già presenti e in files separati una chiave privata e un certificato, per cui il formato JKS non potrebbe essere utilizzato (direttamente) perché keytool non offre un supporto per l’importazione/esportazione della chiave privata. In questo caso si può ricorrere a un archivio PKCS12 e per generare l’archivio si può utilizzare un tool esterno come OpenSSL. Successivamente, si potrà utilizzare il keytool per leggere l’archivio PKCS12.
Il truststore è un archivio per certificati di attori con i quali ci si aspetta di stabilire una comunicazione sicura, a volte contenente certificati di autorità cui è affidato il compito di stabilire il riconoscimento di terze parti. Di norma si limita a mantenere le informazioni relative alla chiave pubblica con la quale si occuperà di eseguire l’autenticazione.
La reale differenza tra i due tipi di archivi sta nel cosa memorizzano e nel relativo scopo. Il keystore serve a fornire credenziali mentre il truststore a verificarle. E’ possibile registrare il certificato di riconoscimento direttamente nel trustore evitando di utilizzare anche il keystore, impiegando così un file al posto di due, ma è buona norma tenere separate le informazioni in due files per una migliore gestione delle risorse.
Nella prossima lezione vedremo all’opera i tools introdotti per degli esempi di creazione di trustores e keystores mentre nelle lezioni successive li utilizzeremo per generare gli archivi usati negli esempi relativi agli scenari di autenticazione a una e a due vie.