AUTENTICAZIONE: SCRAM-SHA256 feat. DH Key Exchange

da

Nella vita di tutti i giorni, l’atto di verifica dell’identità di una persona è di importanza fondamentale. Analogamente, anche in informatica questo processo risulta essere basilare per le moderne comunicazioni. Pensiamo, per esempio, a quando un Client vuole scambiare dati con un Server: esso dovrà inizialmente autenticare la sua identità in modo da acquisire il diritto di ricevere le informazioni richieste e specifiche per sé (conversazione tra il browser web, ad es. Chrome, e un social network come Facebook).

L’informatica è basata su protocolli, ovvero insiemi di regole che, a seconda del contesto, definiscono le modalità con cui questo deve svilupparsi (per esempio quando si consulta un sito web si utilizza il protocollo HTTP). Il contesto di nostro interesse è quello dell’autenticazione e, a tal proposito, analizzeremo un protocollo che, nell’ultimo periodo, sta ottenendo un’attenzione particolare grazie alle sue interessanti caratteristiche che lo differenziano da molti altri.

Questo protocollo è SCRAM, acronimo di Salted Challenge Response Authentication Mechanism. Esso fa parte della famiglia di protocolli di autenticazione Challenge/Response – Sfida/Risposta, caratterizzati dal fatto che uno dei partecipanti alla comunicazione lanci una “sfida” e l’unico modo per essere autenticati sia dare una “risposta” corretta. Il più semplice esempio che possiamo pensare di questa tipologia è la classica autenticazione con password dove il Server richiede al Client la password con la quale si è registrato precedentemente (Challenge) ed il Client deve restituire quella corretta (Response).

Il problema di questo esempio però è che il Server, per verificare la correttezza della password, deve possederla e quindi averla memorizzata (solitamente criptata). Per questo motivo entra in aiuto SCRAM. La caratteristica fondamentale di SCRAM è di permettere una autenticazione con password, senza che essa venga direttamente memorizzata dal server e senza che essa passi mai in chiaro in un canale potenzialmente compromesso. Un altro aspetto interessante è che questo protocollo risulta essere anche molto semplice da implementare.

COME FUNZIONA SCRAM?

Una cosa fondamentale da osservare è che inizialmente, tra i due partecipanti, vi deve essere una fase di scambio di un segreto in comune, ovvero un’informazione nota soltanto ad entrambi, che verrà utilizzato durante la fase di autenticazione. Questo scambio non è gestito dal protocollo ufficiale SCRAM. La nostra trattazione iniziale darà quindi per scontato che entrambi i partecipanti abbiano in comune due segreti, chiamati “Client key” e “Server key”.

Il Client, volendosi registrare ad un Server e successivamente autenticarsi, invia il suo username ed un nonce, ovvero un numero casuale, univoco, che verrà utilizzato durante lo svolgimento del protocollo. Il Server, una volta ricevute queste due informazioni, genera a sua volta un suo nonce, un iteration count ed un salt (entrambi valori numerici di cui a breve capiremo lo scopo), ed invia tutto al Client. A questo punto quest’ultimo genera una password, senza comunicarla, ed applica una funzione chiamata PBKDF2-HMAC – Password-Based Key Derivation Function-keyed Hash Message Authentication Code – ottenendo una salted password.

Questo meccanismo ha la finalità di rallentare notevolmente eventuali attaccanti, qualora riuscissero ad entrare in possesso della salted password durante la sessione in corso. A questo punto il Client invia il risultato al Server in maniera criptata ed entrambi sono in grado di generare gli stessi valori: Client key, dato dall’HMAC tra la salted password e “Client key” e Server key, dato dall’HMAC tra la salted password e “Server key”. La Client key verrà successivamente inserita in una funzione di hash con il fine di ottenere la Stored key. Arrivati a questo punto, entrambi hanno le medesime informazioni e può iniziare la fase di autenticazione.

Tale fase prevede operazioni molto semplici, ma allo stesso tempo molto efficaci e sicure. Entrambi generano un messaggio di autenticazione dato dalla concatenazione di alcuni dati precedentemente scambiati: username, nonce del Client, salt, iteration count e nonce del Server.
Il Client inizia l’autenticazione generando una sua firma, data dall’HMAC tra la stored password e il messaggio di autenticazione precedentemente generato. Con questa firma viene eseguita infine un’operazione chiamata XOR con la Client key al fine di ottenere la prova (Client proof) da inviare al Server. Dalla sua parte, il Server riceve la Client proof ed esegue a sua volta uno XOR con la firma del Client da lui autonomamente generata. Il risultato sarà una Client key. Essa verrà inserita in una funzione di hash e se il risultato finale risulta uguale alla Stored key da lui calcolata sempre in maniera autonoma, l’autenticazione avviene con successo. In tal caso, il Server genera una sua firma data dall’HMAC tra la Server key e il messaggio di autenticazione e la invia al Client. Quest’ultimo la verificherà con il fine di ottenere una prova che stia parlando effettivamente col Server in cui si è precedentemente registrato.

COME FUNZIONA LA NOSTRA IMPLEMENTAZIONE DI SCRAM?

La versione da noi ideata consiste in un’integrazione tra SCRAM ed un algoritmo di scambio di chiavi (Diffie-Hellman), in modo da poter gestire anche le parti non ufficialmente trattate, con un unico algoritmo.

Come ricorderete, all’inizio della spiegazione di SCRAM è stato detto che, prima dell’inizio del protocollo, sia Client che Server devono procedere alla condivisione  di segreti, e di come questa parte non fosse gestita dal protocollo.
Con una piccola variazione , siamo riusciti a integrare entrambe le parti, rendendolo più sicuro e mantenendo nella registrazione il numero di messaggi invariati.

Il Client, invece di inviare inizialmente al Server soltanto il suo username e il suo nonce, gli invia anche la sua chiave pubblica. Essa verrà ricevuta dal Server, il quale a sua volta invierà insieme al salt, all’iteration count e al suo nonce, anche la sua chiave pubblica. A questo punto, l’algoritmo Diffie-Hellman può concludersi, generando la chiave segreta e condivisa che sarà utilizzata per criptare successivamente la salted password inviata dal Client, così come i due segreti “Client key” e “Server key”, i quali verranno creati casualmente dal Server per poi essere inviati.
La parte di registrazione iniziale segue quindi questo flusso

scram

mentre quella di autenticazione è data da

scram

Con questa modifica siamo così in grado di fornire sia una fase di scambio di segreti, sia una fase di autenticazione.

Lo schema completo può essere visionato qui: https://github.com/gpericol/scram

LEGGI ANCHE:

8 modi per prevenire un Attacco Ransomware

Hacking: cosa significa veramente?

We Are Segment e Tormoil fanno il giro del mondo

Ultimi articoli

AI, MACHINE LEARNING, IOT. LA MIA ESPERIENZA A AWS SUMMIT 2023

AI, MACHINE LEARNING, IOT. LA MIA ESPERIENZA A AWS SUMMIT 2023

Giovedì 22 giugno ero al Milano Convention Center in occasione dell'evento annuale organizzato da Amazon Web Services per promuovere i propri servizi Cloud in continua evoluzione: AWS SUMMIT. In mezzo a un mare di IoT, di Servitization, di Cloud Computing sopra le...

TECNOLOGIA E SOSTENIBILITÀ: DUE PAROLE CON ERIC EZECHIELI

TECNOLOGIA E SOSTENIBILITÀ: DUE PAROLE CON ERIC EZECHIELI

Sostenibilità non può essere solo una parola che fa parte del nostro vocabolario quotidiano, ma vuota nei suoi effetti. La tecnologia ha un ruolo di propulsione in questo senso e può aiutare le aziende a raggiungere obiettivi più sostenibili. Abbiamo fatto una lunga...

RAPPORTO CLUSIT 2023: PRESSIONE ALTISSIMA SULLE REALTÀ INDUSTRIALI

RAPPORTO CLUSIT 2023: PRESSIONE ALTISSIMA SULLE REALTÀ INDUSTRIALI

L’Associazione Italiana per la Sicurezza informatica Clusit, ha presentato nei giorni scorsi l’annuale Report degli incidenti di sicurezza più significativi avvenuti a livello globale (Italia inclusa) nel 2022. Il documento è realizzato con la collaborazione di un...