ACN LineeGuida Password
ACN LineeGuida Password
Cybersicurezza Nazionale
LINEE GUIDA
FUNZIONI
CRITTOGRAFICHE
Conservazione delle Password
DICEMBRE 2023
Agenzia per la Cybersicurezza Nazionale
Questo documento, che costituisce parte delle “Linee Guida Funzioni Crittografiche”, elaborato dall’Agenzia per la
Cybersicurezza Nazionale, d’intesa con il Garante per la Protezione dei Dati Personali, contiene le raccomandazioni in
merito alla conservazione delle password.
Il documento tiene in considerazione le minacce presenti al giorno della sua pubblicazione. Data la diversa natura dei
sistemi informativi di destinazione, non è possibile garantire che queste raccomandazioni possano essere utilizzate
senza adattamenti specifici.
In qualsiasi caso, la pertinenza dell’attuazione delle soluzioni proposte deve essere sottoposta, preventivamente, a
valutazione e validazione da parte dei responsabili della sicurezza dei sistemi informativi di destinazione.
Il documento è stato curato, in particolare, da Simone Dutto, Sergio Polese e Giordano Santilli, esperti crittografi in forza
alla Divisione Scrutinio Tecnologico, Crittografia e Nuove Tecnologie del Servizio Certificazione e Vigilanza di ACN.
Si ringraziano per la collaborazione, in particolare, Dorotea Alessandra De Marco e Marco Coppotelli, funzionari
dell’Autorità Garante per la Protezione dei Dati Personali.
Sommario pag.
1. Introduzione 5
2. Password hashing 6
2.1. Il salt 7
2.2. Il pepper 8
2.3. Aggiornamento della funzione di password hashing 8
3. Principali algoritmi 9
3.1. PBKDF2 9
3.2. scrypt 11
3.3. bcrypt 12
3.4. Argon2 13
4. Conclusioni 16
Bibliografia 18
{0, 1} Campo binario dei valori assumibili da ⊕ Operazione XOR, ovvero somma bit a bit
un singolo bit tra stringhe binarie
{0, 1}n Spazio vettoriale delle stringhe binarie int(i) Conversione dell’intero i in una stringa
di lunghezza n binaria di 32 bit
{0, 1}∗ Insieme di stringhe binarie di ⌊x⌋ Parte intera inferiore di x, ovvero il più
lunghezza arbitraria grande intero minore o uguale a x
‖ Concatenazione di stringhe Mi,j L’elemento della matrice M che si trova
nella riga i e colonna j
1 Introduzione
Al giorno d’oggi, l’accesso alla maggior parte dei sistemi e Per tali ragioni, è estremamente raccomandato l’utilizzo di
servizi informatici prevede il superamento di procedure di robuste funzioni crittografiche di password hashing.
autenticazione informatica a uno o più fattori che, spesso, Questo documento ha l’obiettivo di fornire indicazioni e
comprendono l’utilizzo di una parola chiave (password). raccomandazioni sulle funzioni ritenute attualmente più
La gestione delle password è un aspetto fondamentale sicure.
nell’ambito della sicurezza informatica e della protezione Il documento presenta la seguente struttura: nel
dei dati personali. Pertanto, i gestori dei sistemi e servizi capitolo 2 si introduce il concetto di password hashing,
devono prevedere misure tecniche e organizzative efficaci focalizzando l’attenzione sulle proprietà che le funzioni
per l’archiviazione, la conservazione e l’utilizzo delle devono soddisfare e sui possibili attacchi a cui gli archivi
password. di password possono essere soggetti; nel capitolo 3
Gli archivi in cui sono conservate le password finiscono si presentano nel dettaglio gli algoritmi più comuni
sempre più frequentemente nelle mani di soggetti esterni utilizzati per il password hashing. Infine, nel capitolo 4
a seguito di attacchi informatici e vengono poi pubblicati vengono fornite le indicazioni su quali sono gli algoritmi
online o utilizzati per condurre altri attacchi. raccomandati e sui rispettivi parametri.
2 Password hashing
Una funzione di hash prende in input una stringa di fase di salvataggio della password e confrontare il valore
bit di lunghezza arbitraria e restituisce una stringa ottenuto con quello presente all’interno dell’archivio.
di bit di lunghezza fissa, detta digest. I dettagli e le Nonostante il password hashing migliori la sicurezza della
raccomandazioni per le funzioni di hash si possono trovare conservazione delle password, è importante prestare
nel documento dedicato. attenzione ad alcuni aspetti delicati, che possono lasciare
Una delle proprietà delle funzioni di hash crittografiche è spazio a vulnerabilità. Il principale scenario da tenere in
quella di essere one-way, ovvero non invertibile: dato un considerazione è il data breach, ovvero l’incidente in cui
digest, è computazionalmente difficile trovare un input trapela tutta o parte della lista contenente i digest di
che permetta di ottenerlo tramite la funzione di hash. password salvati su un server. Una volta ottenuta la lista
Tale caratteristica rende le funzioni di hash adatte alla delle coppie utente-digest, l’attaccante può procedere per
conservazione delle password: invece che memorizzare forza bruta, cioè calcolando l’hash di password casuali
nell’archivio le password in chiaro, si salva il loro fino a trovare una corrispondenza, oppure può effettuare
digest in modo che qualsiasi soggetto malintenzionato un attacco al dizionario [2]. Questo tipo di attacco sfrutta
eventualmente venuto in loro possesso non possa il fatto che, solitamente, gli utenti scelgono password
disporre direttamente delle password, ma solamente del banali o comunque parole di senso compiuto, per cui un
loro digest. In questo contesto si parla quindi di password malintenzionato potrebbe calcolare l’hash delle password
hashing [1]. L’estrema complessità nell’invertire le funzioni più comuni fino a trovare una corrispondenza all’interno
di hash rende impossibile per l’attaccante il recupero delle della lista trapelata.
password originali degli utenti. Al contrario, è semplice È importante osservare come chiunque sia in possesso
verificare la correttezza della password dell’utente al dell’archivio sia anche in grado di individuare tutti gli utenti
momento della richiesta di accesso, in quanto è sufficiente che utilizzano la stessa password, poiché, in questo caso,
calcolarne il digest tramite la funzione di hash utilizzata in anche i digest sono uguali.
È importante non utilizzare direttamente le comuni funzioni di hash crittografiche, in quanto queste
ultime risultano ottimizzate per effettuare calcoli in maniera molto rapida ed esistono metodi per
velocizzare la generazione dei digest che renderebbero eventuali attacchi molto più veloci.
• due utenti che utilizzano la stessa password avranno o le cifrature dei digest delle password, che andranno
diverso salt e quindi verranno loro associati due diversi confrontati con quelli ottenuti a partire dalle password
digest. Un attaccante, dunque, non potrà individuare inserite dagli utenti.
più utenti che utilizzano la medesima password con
un’unica computazione; 2.3 Aggiornamento della funzione di password hashing
Nel caso in cui si voglia incrementare il livello di sicurezza
• le rainbow table diventano inutilizzabili, in quanto anche
di un sistema di autenticazione che utilizza una vecchia
le password più comuni vengono modificate dal salt e
funzione di password hashing h, adottando un algoritmo
quindi è necessario ricalcolare la tabella aggiungendo
H più sicuro, è necessario provvedere a un aggiornamento
tutti i possibili salt per ogni password, rendendo,
dei digest delle password già salvati nell’archivio. Una
chiaramente, il processo più oneroso.
possibile strategia è riportata di seguito:
Quindi, in generale, il salt non aumenta il livello di
1. si applica la nuova funzione H ai vecchi digest ottenuti
sicurezza della conservazione della password di un utente
tramite h, sostituendo nell’archivio i vecchi valori con
specifico, ma consente di rallentare le capacità offensive
quelli ottenuti, cioè, per ogni password P, si salva
di un attaccante sull’intero archivio in modo direttamente
H(h(P)), invece di h(P). Calcolare il digest di un digest,
proporzionale alla sua dimensione.
infatti, non comporta un rischio per la sicurezza se si
Per poter risultare efficace, il salt dovrebbe:
utilizzano funzioni di password hashing adeguate;
• essere generato casualmente per ogni password;
2. in corrispondenza di ogni elemento contenuto
• avere una lunghezza adeguata, altrimenti un attaccante nell’archivio, si inserisce un flag per tener traccia della
avrebbe comunque la capacità di precalcolare una necessità di aggiornare il digest;
particolare rainbow table, concatenando tutti i possibili
salt alle password più comuni. 3. al primo accesso di ogni utente, se è necessario
aggiornare il digest, dopo aver controllato la
2.2. Il pepper corrispondenza tra H(h(P)) e il valore salvato
Per aggiungere un ulteriore livello di sicurezza, viene, a nell’archivio, si calcola H(P), che viene quindi salvato
volte, sfruttato un altro strumento crittografico chiamato come nuovo valore del digest, e si disattiva il suddetto
pepper [6]. Il pepper è una stringa di bit casuale che, flag. In questo modo, in seguito, verrà utilizzato solo
al contrario del salt, può essere la stessa per tutte le l’algoritmo H.
password nell’archivio, ma deve essere tenuta segreta in In certi contesti, altri metodi che comportano l’obbligo
quanto viene utilizzata come chiave di un HMAC o di un di aggiornamento delle password da parte degli utenti,
meccanismo di cifratura simmetrico applicato al digest salvando direttamente il digest ottenuto con il nuovo
della password. algoritmo di password hashing, potrebbero essere una
Quindi, in caso di pepper, l’archivio conterrà gli HMAC soluzione più rapida.
3 Principali algoritmi
Come osservato precedentemente, è fortemente dall’altra e quindi eseguibili simultaneamente. Nel caso
sconsigliato calcolare un digest per la conservazione questa possibilità esista, l’utilizzatore può solitamente
delle password tramite la semplice applicazione singola scegliere il numero di processi simultanei.
di una funzione di hash crittografica come quelle indicate Queste caratteristiche vengono definite da parametri
nel documento dedicato. In questo ambito, una pratica personalizzabili. Se da un lato viene così resa possibile
comune è adottare funzioni di derivazione di chiave (o l’applicazione in diversi contesti, dall’altro questa libertà
key derivation function) [1], ideate per ottenere una o più richiede una responsabilità nella scelta di parametri che
chiavi segrete a partire da un valore iniziale segreto, come non inficino la sicurezza dell’algoritmo.
ad esempio una master key. Di seguito sono riportate alcune raccomandazioni
Nonostante il differente scopo di costruzione, tali funzioni sugli algoritmi per il password hashing, comprensive di
soddisfano eccellentemente le proprietà richieste per indicazioni sui valori minimi di questi parametri.
il password hashing e quindi sono tra gli algoritmi più
utilizzati. Le funzioni di derivazione di chiave sono spesso 3.1 PBKDF2
configurabili a seconda delle necessità rispetto a tutte o Password Based Key Derivation Function 2 (PBKDF2) è
ad alcune tra le seguenti caratteristiche: una funzione di derivazione di chiave basata su password
• il costo computazionale, solitamente rappresentato dal progettata nel 1999 e pubblicata nel 2000 come parte
numero di iterazioni di una funzione dell’algoritmo che, della serie “Public Key Cryptography Standards” (PKCS)
se aumentato, ne rallenta l’esecuzione; [7]. Queste pubblicazioni fanno parte degli standard
ideati e pubblicati dagli RSA laboratories, una società
• la memoria utilizzata, ovvero la memoria massima
specializzata in sicurezza informatica che possiede, tra gli
necessaria per eseguire l’algoritmo. In questo contesto,
altri, il brevetto del famoso sistema crittografico a chiave
è importante evidenziare che la memoria richiesta
pubblica RSA. Il funzionamento di PBKDF2 è illustrato in
da tutte le operazioni non deve discostarsi molto dal
Figura 1: la funzione prende in input una password P, un
valore massimo, altrimenti questa diversa distribuzione
salt S e, tramite l’applicazione di un HMAC ripetuto per un
potrebbe fornire delle informazioni all’attaccante
numero preimpostato di iterazioni c, calcola una stringa
(attacchi side-channel [1]);
DK di lunghezza len. In formule,
• la possibilità di parallelizzazione, in quanto l’algoritmo
potrebbe essere suddiviso in più parti l’una indipendente DK = PBKDF2(P, S, c, HMAC , len).
Per informazioni più approfondite sugli algoritmi per volte consecutive l’algoritmo HMAC usando sempre la
generare HMAC si rimanda al documento dedicato ai codici password P come chiave. Il valore finale Ti del blocco è lo
di autenticazione del messaggio. XOR (⊕) tra tutti gli stati parziali ottenuti.
Il numero di blocchi ℓ che andranno a comporre DK è il È importante osservare come le operazioni svolte sui
minimo che permette di raggiungere la lunghezza len singoli blocchi siano completamente indipendenti le une
desiderata. Nel caso in cui ℓ > 232, PBKDF2 restituisce dalle altre e quindi i valori finali Ti possano essere ottenuti
un errore e non procede con la computazione. Questo in parallelo.
evita la creazione di un digest eccessivamente lungo da Infine, il valore DK è la concatenazione di tutti gli stati Ti ,
memorizzare. ovvero
Lo stato di partenza per il blocco i-esimo è formato dalla
DK = T1 ∥ . . . ∥ Tℓ ,
concatenazione del salt con il contatore i convertito
in binario da 32 bit (tipo integer), ovvero S ‖int(i). in cui l’ultimo blocco viene troncato in modo da ottenere la
Questo valore viene aggiornato effettuando per c lunghezza len desiderata.
DK = T1 ∥ T2 ∥ ... ∥ Tℓ
Secondo le specifiche del NIST del 2010 [8] e il RFC del 2017 [9], il salt S deve essere lungo almeno
128 bit ottenuti tramite un generatore di numeri casuali approvato nelle raccomandazioni indicate in
[10], [11], [12], il numero di iterazioni c deve essere adeguato alla capacità computazionale del sistema
utilizzato e maggiore di 1000, e len deve essere lungo almeno 112 bit. Va segnalato, tuttavia, che i valori
minimi suggeriti attualmente per questi parametri risultano troppo bassi per permettere una sicurezza
adeguata, tenuto conto delle sempre maggiori capacità computazionali a disposizione degli attaccanti
tramite i processori di ultima generazione (CPU, GPU, ASIC, FPGA). Sono quindi previsti aggiornamenti che
aumenteranno il numero di iterazioni per garantire una sicurezza adeguata ed escluderanno l’utilizzo di
HMAC-SHA-1, attualmente ancora consigliato dal NIST come funzione interna. Al momento, gli studi più
recenti [13] consigliano l’utilizzo di almeno 600.000 iterazioni utilizzando HMAC-SHA256 oppure almeno
210.000 iterazioni con HMAC-SHA512.
3.2 scrypt
scrypt (letto “esse”-crypt in italiano o “es”-crypt in 3. infine, si applica nuovamente una singola iterazione di
inglese) è una funzione di derivazione di chiave basata PBKDF2 con HMAC-SHA256, ma utilizzando i blocchi
su password ideata nel 2009 da Colin Percival [14] [15] ottenuti come salt, così da ottenere
con lo scopo di rendere meno efficaci gli attacchi basati
su implementazioni hardware specializzate. Rispetto DK = PBKDF2(P, P1 ∥ . . . ∥ Pp , 1, HMAC-SHA256, len).
ai predecessori, scrypt prevede un nuovo parametro
La funzione Mix utilizzata all’interno di scrypt introduce il
che può essere personalizzato al fine di rendere
l’algoritmo più sicuro quando utilizzato nel contesto requisito di memoria e capacità computazionale andando
del password hashing, ossia la memoria richiesta per a lavorare sul singolo blocco Pi tramite un’ulteriore
una intera computazione dell’algoritmo. Massimizzare funzione interna chiamata BlockMix descritta in seguito.
la memoria richiesta produce l’effetto di rallentare le L’output X di Mix(P i ,n,r) si ottiene dal seguente
implementazioni hardware specializzate, senza però procedimento:
inficiare le prestazioni delle implementazioni software. 1. copiare Pi nel blocco X;
La funzione prende in input una password P, un salt S,
un parametro n che rappresenta il requisito di memoria 2. costruire n blocchi V1 = X, Vj = BlockMix(Vj –1,r) per
e capacità computazionale (in termini di mebibyte o MiB, ogni 2 ≤ j ≤ n e aggiornare X = Vn;
cioè 220 byte di CPU e RAM necessari), un parametro r che 3. per n volte, calcolare un nuovo indice 1 ≤ j ≤ n
determina la dimensione dei blocchi, un parametro p per la
dipendente da X e aggiornare X = BlockMix(X ⊕ Vj , r).
parallelizzazione e la lunghezza len dell’output:
L’algoritmo BlockMix di scrypt, a sua volta, utilizza un
DK = scrypt(P, S, n, r, p, len). cifrario a flusso chiamato Salsa20, progettato da Daniel
Inizializzazione, elaborazione e finalizzazione di scrypt J. Bernstein nel 2005 [16]. Come descritto in Figura 2,
avvengono nel seguente modo: l’input X viene inizialmente diviso in 2·r blocchi da 512 bit
1. si applica una singola iterazione di PBKDF2 con HMAC- e si applica Salsa20 allo XOR tra il primo e l’ultimo blocco.
SHA256 così da ottenere p blocchi di lunghezza 1024·r Successivamente, lo stato viene aggiornato alternando
bit, ovvero lo XOR con il blocco successivo all’applicazione della
P1 ∥ . . . ∥ Pp = PBKDF2(P, S, 1, HMAC-SHA256, p · 1024 · r); funzione Salsa20. Gli stati intermedi raggiunti dopo ogni
applicazione di Salsa20 costituiscono l’output finale
2. si elaborano i singoli blocchi in parallelo, applicando ad dell’algoritmo, ma vengono riorganizzati in modo tale che
ognuno la funzione Mix descritta in seguito, ottenendo i primi r blocchi dell’output siano quelli di indice dispari e i
per ogni 1 ≤ i ≤ p rimanenti r siano quelli di indice pari, cioè
Pi = Mix(r, Pi , n); BlockMix(X, r) = Y1 ∥Y3 ∥ . . . ∥Y2r−1 ∥Y2 ∥Y4 ∥ . . . ∥Y2r .
X1 X2 ... X2r
...
Y1 Y2 ... Y2r
3.3 bcrypt
A differenza delle altre funzioni descritte in questo b. la funzione di espansione della chiave descritta
documento, bcrypt (“bi”-crypt) è stata ideata in seguito viene utilizzata per aggiornare lo stato σ
specificatamente per essere una funzione di password sfruttando la password e il salt, in formule
hashing e non una funzione di derivazione di chiave. È
σ = Expand(σ, P, S);
stata introdotta da Provos e Mazières nel 1999 [17] e
sfrutta un cifrario a blocchi, nello specifico Blowfish, c. per 2c volte, si alternano espansioni su σ che
implementato in modalità ECB [18]. L’idea è quella di utilizzano solo il salt e solo la password, in modo
creare un algoritmo di key schedule per il cifrario a blocchi da aumentare il costo computazionale dell’intero
che abbia alti requisiti computazionali così da aumentare algoritmo, cioè
i tempi richiesti per eseguire il cifrario, per poi applicare la
cifratura varie volte. σ = Expand(σ, S, 0),
La funzione prende in input la password P, il salt S, lungo
σ = Expand(σ, P, 0);
128 bit, e un parametro c che identifica il numero di cicli
da effettuare, determinando il costo computazionale
necessario per il password hashing. In formule, 2. si crea una stringa di 192 bit costante, definita come
T = “OrpheanBeholderScryDoubt”,
H = bcrypt(P, S, c).
I passi principali sono: che viene cifrata iterativamente per 64 volte con
Blowfish in modalità ECB e stato σ, aggiornando di volta
1. il cifrario a blocchi viene inizializzato tramite una
in volta T con il cifrato ottenuto, ovvero
funzione Setup con costo computazionale dipendente
da c. Nello specifico, Blowfish richiede 18 chiavi di round T = BlowfishECBσ (T );
K 1,…,K 18 da 32 bit e 4 S-box (substitution box)
SB 1,…,SB 4 , che associano output di 32 bit a input di 8 3. il risultato finale è la concatenazione di c con il salt S e il
bit, salvate come look-up table di 1 KB (256 entrate di T ottenuto, in formule
32 bit) ognuna. Questi dati costituiscono lo stato interno
bcrypt(P, S, c) = c ∥ S ∥ T.
σ = (K1 , . . . , K18 , SB 1 , . . . , SB 4 ).
La funzione Expand(σ, P, S) prende in input lo stato σ
Nello specifico, la funzione Setup(P,S,c) esegue i costituito dalle chiavi di round K 1,…,K 18 e dalle S-box
seguenti passi: SB 1,…,SB 4 , una stringa P di lunghezza arbitraria e
a. le cifre della costante π vengono copiate nelle chiavi una stringa S di 128 bit, e svolge delle operazioni di
di round K 1,…,K 18 e nelle singole entrate delle S-box aggiornamento delle chiavi di round e delle S-box
SB 1,…,SB 4 come valore iniziale; effettuando cifrature con Blowfish.
S1 S2
Blowfishσ
K1 K2
Blowfishσ
K3 K4
Blowfishσ
.. .. ..
. . .
K17 K18
Blowfishσ
In particolare, le chiavi di round K 1,…,K 18 dello stato σ modificare anche le S-box, generando due output di S-box
vengono inizialmente aggiornate calcolando lo XOR a ogni passaggio, secondo lo schema in figura. Questo
tra i loro valori iniziali e la stringa di 576 bit ottenuta viene ripetuto per 4·128 volte in modo da aggiornare
ripetendo più volte P. In seguito, S viene diviso in due tutte le entrate di tutte le S-box una volta. Il risultato della
parti da 64 bit l’una, S = S 2 ‖S 1 , che verranno sommate funzione è quindi il nuovo stato σ.
tramite XOR alternativamente ai cifrati parziali ottenuti.
Viene quindi cifrato S 1 con Blowfish usando lo stato σ. Il 3.4 Argon2
risultato corrisponde alla prima coppia di chiavi K 1,K 2 , Nel 2013, un gruppo di crittografi ha aperto un bando per
con le quali si aggiorna lo stato σ e il cui XOR con S 2 viene algoritmi di password hashing [19] per selezionare nuovi
nuovamente cifrato con Blowfish per ottenere K 3 ,K 4 . standard crittografici per la conservazione delle password.
Il procedimento, quindi, viene ripetuto fino a ottenere Alla scadenza per la presentazione degli algoritmi, erano
tutte le chiavi di round. Successivamente, si procede a stati presentati 24 candidati ed è iniziata la Password
Hashing Competition (PHC) [20]. Al termine della gara, principalmente come funzione di derivazione di chiave e
a luglio 2015, soltanto uno di questi algoritmi è stato come funzione di password hashing;
selezionato come vincitore: Argon2. Questa competizione,
• Argon2id, versione mista delle precedenti, che prevede
tuttavia, non fa parte delle classiche selezioni ufficiali del
l’utilizzo di Argon2i nella prima metà del processo e
NIST, ma rientrano in uno sforzo privato della comunità
di Argon2d nella seconda metà, in modo da garantire
scientifica di proporre nuove soluzioni per la salvaguardia
una protezione sia dagli attacchi side-channel, sia dagli
delle password. In seguito a questo risultato e all’assenza
attacchi di forza bruta dedicati.
di attacchi noti in letteratura, alcuni enti internazionali [13]
La funzione prende in input, oltre alla password P, al salt
hanno già riconosciuto Argon2 come la migliore scelta in
S e alla lunghezza len dell’output, anche dei parametri per
generale per il password hashing.
aumentare la complessità computazionale, cioè c per il
Argon2 è una funzione di derivazione di chiave progettata
numero di iterazioni, m per la quantità di memoria e p per
da Alex Biryukov, Daniel Dinu e Dmitry Khovratovich [21].
il grado di parallelizzazione personalizzabile. In formule,
L’algoritmo è progettato per massimizzare il costo degli
attacchi alle password effettuati con macchine ASIC (in DK = Argon2(P, S, c, m, p, len).
grado di ottenere numerosi digest contemporaneamente),
Al suo interno, Argon2 utilizza una funzione di
grazie alla quantità personalizzabile di memoria
compressione f, che trasforma due input di 1024 byte
necessaria durante la sua computazione. Gli autori hanno
ciascuno in un output unico di 1024 byte, e una funzione di
proposto diverse versioni dell’algoritmo:
hash h. In particolare, la documentazione ufficiale ottiene
• Argon2d, che utilizza un accesso alla memoria
h come XOF (extendable output function) a partire da
dipendente dai dati che sta trattando. In questo modo,
Blake2b [22], una versione migliorata della candidata alla
l’algoritmo risulta più resistente ad attacchi perpetrati
competizione per SHA-3 Blake [23].
con strumenti dedicati, come GPU e ASIC, ma più
Come descritto in Figura 4, la funzione f calcola lo XOR
sensibile ad attacchi side-channel. Per queste ragioni,
tra i due input e organizza il risultato in una matrice 8×8
questa versione è dedicata ad applicazioni in blockchain
con entrate da 16 byte ciascuna. Successivamente, tale
e legate alla proof-of-work;
matrice viene modificata applicando π, ovvero la funzione
• Argon2i, che non prevede un accesso alla memoria di round di Blake2b, prima a ogni riga e poi a ogni colonna
dipendente dai dati, risultando quindi più resistente agli della matrice. L’output finale si ottiene calcolando lo XOR
attacchi side-channel. Tale versione viene utilizzata tra la matrice ottenuta e la matrice iniziale.
X1 ⊕ Y 1 ... X8 ⊕ Y 8 π
X9 ⊕ Y 9 . . . X16 ⊕ Y16 π
.. .. .. ..
. . . .
X57 ⊕ Y57 . . . X64 ⊕ Y64 π
Z1 ... Z8
Z9 ... Z16
.. .. π ... π
..
. . .
Z57 ... Z64
Argon2 elabora gli input calcolando un digest della Se il costo c è strettamente maggiore di 1, la matrice B
password, del salt e di una serie di altri parametri iniziali viene aggiornata c –1 volte nel modo seguente:
con la funzione di hash h e genera lo stato iniziale H. In
Bi,1 = Bi,1 ⊕ f (Bi,q , Bi′,j ′ ), 1 ≤ i ≤ p,
seguito, viene generata una matrice B con p righe e
q = 4 · ⌊m/4p⌋ colonne, composta da blocchi di 1024 byte Bi,j = Bi,j ⊕ f (Bi,j−1 , Bi′,j ′ ), 1 ≤ i ≤ p, 2 ≤ j ≤ q.
ottenuti come
Bi,1 = h(H ∥ 0 ∥ i), 1 ≤ i ≤ p, La scelta degli indici i e j viene svolta in modo che ad
Bi,2 = h(H ∥ 1 ∥ i), 1 ≤ i ≤ p, ogni passo sia possibile svolgere p operazioni in parallelo
rispetto all’indice di riga.
Bi,j = f (Bi,j−1 , Bi′,j ′ ) 1 ≤ i ≤ p, 3 ≤ j ≤ q,
Infine, l’output finale si ottiene applicando la funzione di
dove gli indici i e j sono determinati in modo differente hash h allo XOR tra gli elementi dell’ultima colonna della
nelle diverse versioni di Argon2, determinando le matrice B, cioè:
caratteristiche descritte precedentemente. DK = h(B1,q ⊕ B2,q ⊕ . . . ⊕ Bp,q ).
4 Conclusioni
A conclusione delle analisi effettuate in questo avanzamenti e miglioramenti ottenuti dagli altri algoritmi.
documento, si raccomanda l’utilizzo degli algoritmi di Infine, scrypt e Argon2id risultano gli algoritmi più robusti
password hashing indicati in Tabella 1, dove sono anche ed efficienti e dovrebbero essere prioritari rispetto a
riportati i parametri minimi consigliati per i diversi qualsiasi altra scelta.
algoritmi. Per quanto riguarda i parametri minimi di Argon2id, si
In generale, l’uso di un salt risulta una condizione sottolinea come aumentare il grado di parallelizzazione
obbligatoria per qualsiasi algoritmo di password hashing e p richieda necessariamente l’aumento di almeno uno
si sconsiglia l’utilizzo di soluzioni personalizzate. degli altri due parametri, ovvero il numero di iterazioni
L’algoritmo PBKDF2 deve garantire una sicurezza c e la memoria richiesta m. Si raccomanda, in ogni caso,
adeguata, pertanto si raccomanda l’utilizzo delle sole di valutare una dimensione adeguata dei parametri di
funzioni di hash indicate nel documento dedicato, Argon2id in base alla propria capacità computazionale e
massimizzando il numero c di iterazioni. di memoria, in modo da garantire una rapida esecuzione
Per quanto riguarda bcrypt, esso risulta alquanto datato su una singola password, ma tale da rendere infattibile un
e non viene raccomandato, visto anche il numero di numero elevato di esecuzioni.
Algoritmo Parametri
Requisito di Grado di
Lunghezza Lunghezza del Dimensione dei
memoria e capacità parallelizzazione
minima del salt digest (len) blocchi (r)
computazionale (n) (p)
128 MiB 1
scrypt 64 MiB 2
16 MiB 5
8 MiB 10
Grado di
Lunghezza Lunghezza del Numero di Requisito di
parallelizzazione
minima del salt digest (len) iterazioni (c) memoria (m)
(p)
1 46 MiB
2 19 MiB
5 7 MiB
1 2048 MiB
256 bit 4
3 64 MiB
Bibliografia
[1] D. Stinson e M. Paterson, Cryptography: theory and practice, CRC press, 2018.
[2] R. Shirey, «RFC 4949 - Internet Security Glossary, Version 2,» 2007.
[3] L. Grover, «A fast quantum mechanical algorithm for database search,» in Proceedings of the twenty-eighth annual ACM
symposium on Theory of computing, 1996.
[4] P. Oechslin, «Making a faster cryptanalytic time-memory trade-off,» in Advances in Cryptology - CRYPTO, 2003.
[6] U. Manber, «A simple scheme to make passwords based on one-way functions much harder to crack,» Computers &
Security, vol. 15, n. 2, pp. 171-176, 1996.
[7] B. Kaliski, «RFC 2898 - PKCS #5: Password-Based Cryptography Specification,» 2000.
[8] NIST, «SP 800-132 - Recommendation for Password-Based Key Derivation Part 1: Storage Applications,» 2010.
[9] K. Moriarty, B. Kaliski e A. Rusch, «RFC 8018 - PKCS #5: Password-Based Cryptography Specification, Version 2.1,» 2017.
[10] International Organization for Standardization, «ISO/IEC 20543:2019: Information technology - Security techniques - Test
and analysis methods for random bit generators within ISO/IEC 19790 and ISO/IEC 15408,» 2019.
[11] NIST, «SP 800-90A - Recommendation for Random Number Generation Using Deterministic Random Bit Generators,»
2015.
[12] NIST, «SP 800-90B - Recommendation for the Entropy Sources Used for Random Bit Generation,» 2018.
[13] OWASP, «Password Storage Cheat Sheet,» 2023. [Online]. Available: https://cheatsheetseries.owasp.org/cheatsheets/
Password_Storage_Cheat_Sheet.html. [Consultato il giorno 28 Giugno 2023].
[14] C. Percival, «Stronger key derivation via sequential memory-hard functions,» 2009.
Bibliografia
[15] C. Percival, «RFC 7914 - The scrypt Password-Based Key Derivation Function,» 2016.
[16] D. J. Bernstein, «The Salsa20 Family of Stream Ciphers,» in New Stream Cipher Designs: The eSTREAM Finalists, 2008.
[17] N. Provos e D. Mazières, «A Future-Adaptable Password Scheme,» in USENIX Annual Technical Conference, 1999.
[18] B. Schneier, «Description of a New Variable-Length Key, 64-Bit Block Cipher (Blowfish),» in Fast Software Encryption (FSE),
1993.
[19] «PHC call for submissions,» 2013. [Online]. Available: https://www.password-hashing.net/cfh.html. [Consultato il giorno
03 Luglio 2023].
[20] «Password Hashing Competition,» 2015. [Online]. Available: https://www.password-hashing.net/. [Consultato il giorno
03 Luglio 2023].
[21] A. Biryukov, D. Dinu e D. Khovratovich, «RFC 9106 - Argon2 Memory-Hard Function for Password Hashing and Proof-of-
Work Applications,» 2021.
[22] J.-P. Aumasson, S. Neves, Z. Wilcox-O’Hearn e W. Christian, «BLAKE2: Simpler, Smaller, Fast as MD5,» in Applied
Cryptography and Network Security, 2013.
[23] J.-P. Aumasson, W. Meier, R. Phan e L. Henzen, The Hash Function BLAKE, Berlino: Springer, 2014.