Salt (crittografia)
# Salt (crittografia)

In crittografia, un salt è una sequenza casuale di bit utilizzata assieme ad una password come input a una funzione unidirezionale, di solito una funzione hash, il cui output è conservato al posto della sola password, e può essere usato per autenticare gli utenti.

Il salt è usato per salvaguardare le password salvate in memoria. Storicamente le password erano salvate in un file di testo nel sistema, ma con il tempo sono state adottate tecniche che tutelassero maggiormente la sicurezza di queste per evitare che queste fossero lette da un ipotetico utente malevolo. Il salt è una di queste tecniche.

Il salt viene generato casualmente ogni volta che viene generata una password.

Usando dati salt si complicano gli attacchi a dizionario, quella classe di attacchi che sfruttano una precedente cifratura delle voci di un elenco di probabili parole chiave per confrontarle con l'originale: ogni bit di salt utilizzato raddoppia infatti la quantità di memorizzazione e di calcolo necessari all'attacco.

Di solito, il salt viene salvato assieme al numero di iterazioni (key stretching) e all'output della funzione unidirezionale, ma per aumentare la sicurezza è abitudine tenere segreto il valore salt e conservarlo separatamente dal database delle password. Ciò fornisce un vantaggio quando viene rubato il database con le password, ma non il salt. Per scoprire una password da un hash rubato, infatti, un utente malintenzionato non può limitarsi a provare password comuni (ad esempio le parole o i nomi della lingua italiana), ma è costretto a calcolare gli hash di caratteri casuali (almeno per la parte dell'input che si pensa essere il salt), il che è molto più lento.

Il salt è strettamente legato al concetto di nonce, un numero casuale da usare una sola volta in una comunicazione crittografata: ad esempio, i nonce vengono usati nel protocollo HTTP in alcune operazioni di calcolo del digest della password.

## Esempio

Si supponga che la chiave segreta di un utente venga rubata da un database sotto forma di hash, e che sia noto che la password originale fosse una delle 200 000 parole della lingua italiana. Sapendo che il sistema utilizza un valore salt lungo 32 bit, gli hash pre-calcolati dell'attaccante non sono più di alcuna utilità: in questo caso, un utente malintenzionato dovrebbe calcolare l'hash di ogni parola con ognuno dei $2^{32}$ (4 294 967 296) possibili valori salt, fino a trovare una corrispondenza. Il numero totale di tentativi possibili può essere ottenuto moltiplicando il numero di parole nel dizionario con il numero di valori salt possibili:

    ${2^{32}\times 200\,000\approx 8{,}5899\times 10^{14}}$

Per completare un attacco a forza bruta, l'attaccante dovrebbe calcolare circa 800 000 miliardi di hash, invece di soli 200 000. Anche sapendo che la password stessa è semplice, il valore del salt rende molto più difficile individuare la password.

## Esempio d'uso

Di seguito un esempio di come viene utilizzato il salt nel salvataggio di una password.

| Username | Password |
| - | - |
| user1 | password123 |
| user2 | password123 |

La prima tabella contiene username con relative password (che ai fini dell'esempio sono volontariamente identiche) di due ipotetici utenti distinti.

Il valore del salt è generato in modo casuale e viene aggiunto in coda al testo della password. Di tale stringa viene poi calcolata la funzione di hash. Quest'ultima verrà poi memorizzata insieme al valore del salt.

| Username | Valore del salt | Password + Salt | Hashed value = SHA256 (Password + Salt) |
| - | - | - | - |
| user1 | E1F53135E559C253 | password123E1F53135E559C253 | 72AE25495A7981C40622D49F9A52E4F1565C90F048F59027BD9C8C8900D5C3D8 |
| user2 | 84B03D034B409D4E | password12384B03D034B409D4E | B4B6603ABC670967E99C7E7F1389E40CD16E78AD38EB1468EC2AA1E62B8BED3A |

Come si può notare, differenti valori di salt hanno creato due stringhe hash completamente diverse, nonostante le password siano le medesime.

In ogni caso le tecniche di salting non possono garantire una protezione robusta in caso di password molto comuni o facilmente deducibili.

## Errori comuni

### Riutilizzo dello stesso salt

Usare lo stesso salt per ogni input significa che tutte le password uguali avranno lo stesso valore hash. Questo rende facile attaccare utenti multipli decodificando un solo hash.

### Salt troppo corto

Se il valore del salt è troppo piccolo, sarebbe facile per un attaccante creare una rainbow table contenente ogni possibile combinazione di password e salt. Utilizzare un salt di lunghezza opportuna garantisce una protezione maggiore a tale tipo di attacco.

## Benefici

Per comprendere la differenza tra il cracking di una singola password e un insieme di password, si consideri un singolo file che contiene centinaia di nomi utente e password con hash.

Senza salt, un utente malintenzionato può calcolare la funzione hash(tentativo[0]) e quindi verificare se tale hash appare in qualsiasi punto del file. La probabilità di una corrispondenza, ovvero il cracking di una delle password con quel tentativo, aumenta con il numero di password nel file.

Se è presente il salt invece, l'attaccante deve calcolare la funzione hash(salt[a], tentativo[0]) e confrontarla con l'ingresso A; successivamente calcolerà hash(salt[b], tentativo[0]) e confrontarla con l'ingresso B. E così via. Ciò sconfigge il "riutilizzo" degli hash nei tentativi di crackare più password.

L'utilizzo del salt combatte anche l'uso delle tabelle hash e delle rainbow table per crackare le password. Una tabella hash è un ampio elenco di hash precedentemente calcolati per le password comunemente utilizzate e conosciute. Per un file di password senza salt, un utente malintenzionato può esaminare ciascuna voce e cercare la password con hash nella tabella hash o nella rainbow table. Se la ricerca è considerevolmente più veloce del calcolo della funzione hash (che spesso è), questo velocizzerà notevolmente il crack del file. Tuttavia, se il file contiene password con salt, la tabella hash o la rainbow table devono contenere il campo password+salt di cui si dovrà calcolare l'hash. Se il salt è abbastanza lungo e sufficientemente casuale, la probabilità di riuscita di questa tecnica è notevolmente bassa. Le password scelte dagli esseri umani tendono ad essere vulnerabili agli attacchi a dizionario poiché devono essere sia brevi che sufficientemente significative per essere ricordate. Anche un piccolo dizionario (o il suo equivalente hash) è un aiuto significativo per decifrare le password più comunemente utilizzate. Dal momento che i salt non devono essere memorizzati dagli utenti, possono rendere la dimensione delle rainbow table proibitive ai fini di un attacco di questo tipo.

I moderni sistemi di salvataggio delle password, in cui gli hash delle password e altri dati di sicurezza sono archiviati in un file non pubblico, attenua un po' questi problemi. Tuttavia, rimangono rilevanti nei contesti multi-server che utilizzano sistemi di gestione delle password centralizzati per inviare password o hash delle stesse a più sistemi. In tali situazioni, l'account di root su ogni singolo sistema può essere trattato come meno affidabile rispetto agli amministratori del sistema di password centralizzato, quindi vale la pena assicurarsi che la sicurezza dell'algoritmo di hashing della password, inclusa la generazione di valori di salt unici, sia adeguato.

## Implementazioni Unix

Le prime versioni di Unix usavano il file passwd (/etc/passwd) per conservare gli hash delle password con salt (password con anteposti due caratteri di salt casuali). Si noti che in queste vecchie versioni di Unix anche il salt era memorizzato in chiaro nel file passwd, insieme con l'hash delle password con salt, e che tutti gli utenti del sistema potevano leggerlo: il permesso di lettura era necessario perché alcune applicazioni potessero accedere a nomi utente e altre informazioni. In questo modo, quindi, la sicurezza della password era protetta solo dalle funzioni di hashing impiegate.

## Implementazioni nelle applicazioni web

Molte applicazioni web conservano le password degli utenti sotto forma di hash in un database. Senza alcun valore salt, un attacco di SQL injection a buon fine condurrebbe alla probabile compromissione delle password. Dato che molti utenti riutilizzano le proprie password su siti diversi, il valore salt è una componente essenziale per la sicurezza di una web application.

