Nella scorsa lezione abbiamo presentato i diversi tipi di certificati SSL esistenti ma abbiamo volutamente tralasciato l'approfondimento su come un certificato SSL possa, di fatto, dare inizio a un collegamento sicuro e a prova di malintenzionato.
L'uso dei certificati SSL ci permette infatti di proteggere lo scambio di dati online tra un client e un server. Le tematiche che necessitano una trattazione più dettagliata riguardano la crittografia, l'autenticazione e l'integrità dei dati.
In questa lezione ci occuperemo del primo di questi, ovvero della crittografia.
Canali di comunicazione cifrati
La funzione più elementare che un client può eseguire con un server SSL è quella di stabilire un canale di comunicazione criptato.
SSL a tal proposito utilizza 9 messaggi per negoziare un canale di comunicazione criptato, come mostrato nella figura sotto riportata:
- Il client invia un messaggio
ClientHello
proponendo le opzioni SSL. - Il server risponde con il messaggio
ServerHello
selezionando le opzioni. - Il server invia le sue informazioni sulla chiave pubblica nel messaggio
ServerKeyExchange
. - Il server conclude la sua parte di negoziazione con il messaggio
ServerHello-Done
. - Il client invia le informazioni sulla chiave di sessione (criptate con la chiave pubblica del server) nel messaggio
ClientKeyExchange
. - Il client invia il messaggio
ChangeCipherSpec
per attivare le opzioni negoziate per tutti i futuri messaggi che invierà. - Il client invia il messaggio
Finished
per permettere al server di controllare le nuove opzioni attivate. - Il server invia il messaggio
ChangeCipherSpec
per attivare le opzioni per tutti i futuri messaggi che invierà. - Il server invia un messaggio
Finished
per permettere al client di controllare le nuove opzioni appena attivate.
Nei successivi paragrafi esamineremo nel dettaglio i punti sopra elencati.
Messaggi del Client
Il messaggio ClientHello
è quello che di fatto inizia la comunicazione SSL tra le due parti.
Il client usa questo messaggio per chiedere al server di iniziare a negoziare i servizi di sicurezza per mezzo di SSL.
Questo messaggio è formato da diversi campi: Field
, Version
, RandomNumber
, SessionID
, CipherSuites
, CompressionMethods
.
Il campo Version
del messaggio contiene il numero di versione SSL che il client può supportare.
La versione attuale è la 3.0 ed è la più diffusa su Internet. Chiaramente un client è in grado di supportare tutte le versioni precedenti a quelle del valore specificato in questo campo (retroattività).
Il campo RandomNumber
contiene un numero casuale. Questo valore, insieme ad un valore casuale simile che il server crea, fornisce il seme per i calcoli crittografici.
La specifica SSL suggerisce che quattro dei 32 byte di questo campo consistano nell'ora e nella data. Il protocollo SSL non richiede un particolare livello di accuratezza per questo valore, poiché non è inteso a fornire un'indicazione accurata dell'ora.
La specifica suggerisce invece di usare la data e l'ora come un modo per assicurare che il client non usi mai lo stesso valore casuale due volte.
Questa precauzione ci protegge da un impostore che copia vecchi messaggi SSL da un client legittimo e che li riutilizza per stabilire una sessione contraffatta.
I restanti 28 byte di questo valore dovrebbero essere un numero casuale "crittograficamente sicuro".
La maggior parte dei programmi per creare numeri casuali usano una tecnica conosciuta come generazione di numeri pseudocasuali. Questo approccio, se usato correttamente, produce dei numeri che in qualche modo risultano casuali.
Tuttavia, la tecnica ha un grave difetto quando viene utilizzata in un contesto di sicurezza: se un attaccante conosce l'algoritmo esatto per la generazione dei numeri casuali, questo può predire correttamente tutti i futuri valori casuali.
Questa conoscenza potrebbe permettere all'attaccante di anticipare un particolare valore e preparare un attacco. Per prevenire questa problematica le implementazioni di SSL usano una tecnica basata su algoritmi crittografici.
Il campo CipherSuites
permette a un client di elencare al server i vari servizi crittografici che può supportare, inclusi gli algoritmi esatti e le dimensioni delle chiavi. Il server prende la decisione finale su quali servizi crittografici usare per la comunicazione, ma è comunque limitato a scegliere da questa lista.
Il campo CompressionMethods
è, in teoria, simile al campo CipherSuites
. Anche in questo caso il client può elencare tutti i vari metodi di compressione dei dati che è in grado di supportare.
I metodi di compressione sono una parte importante di SSL perché la crittografia cambia le proprietà matematiche delle informazioni in un modo modo che rende la compressione dei dati virtualmente impossibile.
Infatti, se fosse possibile comprimere i dati crittografati, ciò indicherebbe probabilmente una debolezza a livello di sicurezza nell'algoritmo di crittografia.
Per questo motivo, se due parti stanno per utilizzare la compressione dei dati per una comunicazione, è importante che comprimano i loro dati prima di crittografarli.
Il protocollo SSL adotta questo comportamento assicurandosi che la compressione avvenga prima della crittografia.
Nella versione corrente di SSL non sono stati definiti metodi di compressione.
Messaggi del Server
Quando il server riceve il messaggio ClientHello
, risponde con un ServerHello
. Il contenuto di un ServerHello
è molto simile a quello di un ClientHello
anche se sono presenti alcune importanti differenze che esamineremo a breve.
La versione del ClientHello
identifica semplicemente quali versioni di SSL il client può supportare. La versione del ServerHello
, invece, determina la versione SSL che verrà utilizzata nella comunicazione.
Un server non è completamente libero di scegliere qualsiasi versione SSL, tuttavia; non può scegliere una versione più recente dell'ultima che il client può supportare. Se al client non piace la scelta del server, questo può abbandonare la comunicazione.
Il campo RandomNumber
del ServerHello
è essenzialmente lo stesso del ClientHello
, anche se questo valore casuale è scelto dal server. Insieme al valore del client, questo numero viene adoperato per importanti calcoli crittografici.
Il valore del server condivide le stesse proprietà del ClientHello
. Quattro dei 32 byte sono la data e l'ora ora (per evitare di ripetere valori casuali); i restanti byte dovrebbero essere creati da un generatore di numeri casuali crittograficamente sicuro.
Il campo SessionID
di un ServerHello
può contenere un valore, a differenza del campo ClientHello
. Il valore in questo caso identifica univocamente la particolare comunicazione o sessione SSL.
Il campo CipherSuite
(al singolare e non al plurale, come nel caso del ClientHello
) determina gli esatti parametri crittografici e in particolare gli algoritmi e le dimensioni delle chiavi, da usare per la sessione.
Il server deve selezionare una sola suite di cifratura tra quelle elencate dal client nel suo messaggio ClientHello
.
Il campo CompressionMethod
(al singolare e non al plurale, come nel caso del ClientHello
) usa questo campo per identificare la compressione dei dati da usare per la sessione. Anche questa volta il server deve scegliere tra quelli elencati nel ClientHello
.
Al punto 3 il server invia al client un messaggio di tipo ServerKeyExchange
. Quello che fa questo messaggio è completare il campo CipherSuite
del messaggio ServerHello
precedente.
Il campo CipherSuite
indica gli algoritmi crittografici e le dimensioni delle chiavi, mentre questo contiene le informazioni sulla chiave pubblica adoperata.
Il client userà la chiave pubblica del server per cifrare una chiave di sessione che le parti useranno successivamente per crittografare effettivamente la comunicazione.
Il messaggio ServerHelloDone
dice al client che il server ha finito con i suoi messaggi di negoziazione.
Il messaggio in sé non contiene altre informazioni ma è importante per il client perché, una volta ricevuto, gli fa capire di poter passare alla fase successiva in cui stabilire una comunicazioni sicura.
Quando il server ha finito la sua parte della negoziazione iniziale SSL, il client risponde con un messaggio ClientKeyExchange
. Proprio come il ServerKeyExchange
, questo gli fornisce le informazioni sulla sua chiave pubblica.
A questo punto client e server sono in grado di poter cifrare le proprie comunicazioni per mezzo della rispettive chiavi pubbliche. Es: il client può cifrare i messaggi usando la chiave pubblica del server.
Questa crittografia, di fatto una crittografia asimmetrica, protegge le informazioni mentre attraversano la rete e permette al client di verificare che il server possieda veramente la chiave privata corrispondente alla sua chiave pubblica. Altrimenti, il server non sarà in grado di decifrare il messaggio.
Questa operazione fornisce una protezione importante contro un attaccante che intercetta messaggi da un server legittimo e finge di essere quel server, inoltrando i messaggi ad un client ignaro.
Poiché un falso server non conoscerà la chiave privata del server reale, questo non sarà comunque in grado di decifrare il messaggio ClientKeyExchange
.
Conclusioni
Nella prossima lezione ci occuperemo della autenticazione e integrità in SSL/TLS.