• Non ci sono risultati.

CAPITOLO 5 – PROGETTO PROTOTIPO

5.3 SICUREZZA DEGLI ACCESSI

5.3.1 Generazione delle password

Iniziamo adesso ad analizzare in dettaglio il processo di autenticazione, partendo dalla modalità di generazione delle password. Durante la prima fase è previsto l’inserimento da parte dell’utente del proprio Codice Fiscale, che viene confrontato con quelli custoditi nel database del server; se l’utente risulta essere presente è possibile procedere con la seconda fase, altrimenti è necessario ripetere l’operazione. Per evitare attacchi da parte di malintenzionati non è possibile inserire più di un certo numero di codici errati e, a seguito di ciò, l’indirizzo IP del client viene bloccato. È nella fase successiva che viene creata, lato server, la One-Time Password (OTP). Si tratta di un codice casuale di 8 cifre che, come dice il nome, può essere utilizzato una sola volta e per di più ha una durata temporale limitata a partire dal momento della sua creazione. A seguito di un’avvenuta autenticazione o alla scadenza dell’intervallo di tempo previsto, tale codice diventa inutilizzabile. Per evitare un consumo eccessivo di risorse su disco e garantire una maggiore sicurezza, le informazioni necessarie alla gestione delle OTP vengono create dal Web Service (tramite la classe Java SecureRandom) al momento della generazione di una richiesta di accesso e risiedono in una tabella del database, in relazione 1:1 con ciascun utente, solo per il tempo strettamente necessario al completamento della procedura di autenticazione. Il generatore di codici utilizzato segue lo standard IETF RFC 6238 (TOTP – Time Based OneTime Password) pubblicato nel maggio del 2001, e al quale fa riferimento anche Google Authenticator; rappresenta un’estensione dell’algoritmo OTP classico con aggiunta di una dipendenza dalla variabile temporale. La procedura si basa sull’applicazione dell’algoritmo HMAC SHA-512 al valore di un contatore di eventi temporali

Firewall Server DataBase Utente Firewall Web Service HTTPS JDBC SOAP

(contatore di intervalli di 30 secondi a partire dalla mezzanotte del 1 Gennaio 1970) che rappresenta il messaggio nel calcolo dell’HMAC. Il risultato restituito, della lunghezza di 512 bit (64 byte), viene poi “troncato” in modo da ottenere un valore user-friendly, quindi di una lunghezza non eccessiva e semplice da leggere/scrivere per l’utilizzatore, ma sempre nel rispetto dei vincoli imposti dalla normativa.

HOTP(K,C) = Truncate(HMAC-SHA-512(K,C))

Con K si indica la chiave segreta mentre con C il valore del contatore. L'HMAC SHA-512 non è un algoritmo di cifratura, ma un algoritmo Hash che trasforma una stringa di byte in un’altra stringa di byte. Ricordiamo che questo algoritmo non è reversibile, il che significa che non è possibile utilizzare il risultato per risalire alla fonte. Un HMAC SHA-512 utilizza una chiave segreta per poter effettuare la trasformazione. La sua lunghezza deve essere di 64 byte, il contatore degli eventi temporali è a 8 byte ed il risultato è un numero di 8 cifre. Questo significa che ci saranno ovviamente dei duplicati durante il tempo di vita del generatore di codici, ma ciò non importa dato che la OTP è valida solo per pochi minuti. Si può notare subito quali sono le diverse ragioni che rendono questo tipo di procedura affidabile:

 lunghezza della chiave;

 la password è valida per un tempo limitato:

 l’algoritmo che genera ciascuna password non è reversibile;

 se la OTP è ricevuta sul cellulare, la chiave segreta rimane sempre nel server e solo per il tempo strettamente necessario al completamento di una singola procedura di autenticazione. In un normale processo di autenticazione con password statiche, il punto debole è tipicamente costituito dal fattore umano; è difficile ricordare molte password complesse, così gli utenti utilizzano spesso la stessa in tutto il web. Con una OTP invece non c'è bisogno di ricordare nessuna password, e la sicurezza delle credenziali è garantita dal gestore del servizio.

Figura 27 – E’ importante utilizzare password non banali per avere un buon livello di sicurezza..

Volendo trovare una possibile debolezza, questa può essere rappresentata dai supporti utilizzati per ricevere la OTP: in caso di smarrimento degli stessi infatti, l’autenticazione dell’utente potrebbe essere momentaneamente compromessa. La verifica dell’identità dell’utente secondo queste

modalità riduce drasticamente le probabilità che le informazioni personali di un account siano rubate da terzi. Questo perché gli hacker dovrebbero non solo riuscire ad ottenere l’username (il Codice Fiscale in questo caso), ma dovrebbero anche riuscire ad ottenere la chiave personale utilizzata dall’algoritmo per generare la combinazione di otto cifre. Tale chiave deve ovviamente essere segreta e custodita in un supporto sicuro. Questo requisito risulta essere soddisfatto dalle misure, sia di tipo hardware che software, che la Fondazione utilizza per i suoi server e per i dati in essi contenuti, come ad esempio i firewall che impediscono ai malintenzionati di accedere alla rete privata. Tornando alla descrizione del generatore di codici utilizzato, abbiamo definito un TOTP come:

TOTP = HOTP(K,T)

T= (UNIX Time corrente – T0)/X

dove T è un intero che rappresenta il numero di istanti temporali che intercorrono tra l’istante di tempo T0 del contatore e l’UNIX Time corrente, mentre X rappresenta la lunghezza di ogni intervallo temporale. Per descrivere più semplicemente il processo di generazione del codice facciamo riferimento ad un esempio numerico, ipotizzando di ricorrere ad un HMAC SHA-1 e di voler ottenere come uscita una OTP di 6 cifre. Queste ipotesi ci permettono di semplificare i calcoli ed esprimere meglio i concetti dato che la procedura rimane essenzialmente la stessa, ma l’HMAC SHA-1 produce un digest più corto rispetto all’HMAC SHA-512 (20 byte e 64 byte rispettivamente). Consideriamo dunque un generico istante temporale:

secret_key = 12345678901234567890

hash_hmac ('sha1', T, secret_key)

Result: af2b88048d48979b528af4e37085061d88aaaaa5

Vediamo come convertire questo risultato in una sequenza di 6 caratteri. Per prima cosa si converte il risultato in un array esadecimale, secondo la mappatura di seguito riportata.

Array ( [0] => af [1] => 2b [2] => 88 [3] => 04 [4] => 8d [5] => 48 [6] =>

97 [7] => 9b [8] => 52 [9] => 8a [10] => f4 [11] => e3 [12] => 70 [13] => 85 [14] => 06 [15] => 1d [16] => 88 [17] => aa [18] => aa [19] => a5 )

Dopodiché si prende il 19-esimo byte dell’array, che in questo caso corrisponde al valore esadecimale 0xa5, e si calcola il valore di offset dato dall’operazione di AND bit a bit tra il valore appena ricavato e la maschera 0xF. In questo caso si ottiene 0x5, che è pari a 5 in decimale. A questo punto, partendo quindi dal byte 5, vengono selezionati i primi 4 byte dell’array ottenendo 0x48979B52 che in decimale è pari a 1217895250. Per generare la TOTP di lunghezza n si prende il modulo 10^n del risultato appena ottenuto: in questo esempio n=6, dunque TOTP = 1217895250 mod 10^6 = 895250.