Password Hashing: aggiungere sale + pepe o sale abbastanza?

213

Nota: sono a conoscenza del fatto che il metodo corretto per l'hashing di archiviazione delle password protette è scrypt o bcrypt. Questa domanda non è per l'implementazione nel software attuale, è per mia comprensione.

correlati

Sfondo
Per quanto ne so, il metodo raccomandato / approvato per l'archiviazione dei verificatori di password è quello di memorizzare:

$verifier = $salt + hash( $salt + $password )

Dove:

  • hash() è un algoritmo di hashing crittografico
  • $salt è un valore di entropia casuale, uniformemente distribuito,
  • $password è la password inserita dall'utente

Alcune persone consigliano di aggiungere una chiave segreta nel mix (a volte chiamata pepper ). Dove il pepe è un segreto, alta entropia, costante specifica del sistema.

La logica sembra essere che anche se l'attaccante si impossessa dei verificatori della password, ci sono buone possibilità che lui o lei non conoscano il valore del pepe. Quindi montare un attacco riuscito diventa più difficile.

Quindi, la mia domanda è:
Aggiunge un valore di pepe in aggiunta a un sale quando le password di hashing aumentano la sicurezza generale?

Oppure la percezione di una maggiore sicurezza basata su false ipotesi?

Aggiornamento rapido
Conosco lo scopo del $salt (ho scritto abbastanza una risposta lunga su StackOverflow a riguardo) la chiave $pepper aggiuntiva è non che migliora il funzionamento del sale.
La domanda è: il $pepper aggiunge una sicurezza altro di quello che fa il sale?

    
posta Jacco 22.04.2011 - 11:53
fonte

7 risposte

179

In alcune circostanze, i peperoni possono essere utili.

Come esempio tipico, diciamo stai creando un'applicazione web. Si compone di codice webapp (in esecuzione in alcuni framework webapp, ASP.NET MVC, Pyramid su Python, non importa ) e un database SQL per l'archiviazione. La webapp e il DB SQL vengono eseguiti su server fisici diversi .

L'attacco più comune contro il database è un attacco SQL Injection di successo. Questo tipo di attacco non ha necessariamente accesso al tuo codice webapp, perché la webapp funziona su un server diverso e amp; user-ID.

Devi memorizzare le password in modo sicuro nel database e trovare qualcosa sotto forma di:

$hashed_password = hash( $salt . $password )

dove $salt è memorizzato in testo normale nel database, insieme alla rappresentazione $hashed_password e scelti casualmente per ogni password nuova o modificata .

Il aspetto più importante di ogni schema di hashing delle password è che hash è una funzione hash crittografata slow , vedi link per ulteriori informazioni di base.

La domanda è quindi, dato che è quasi zero l'impegno di aggiungere un valore costante al codice dell'applicazione e che il codice dell'applicazione non tipicamente verrà compromesso durante un SQL Injection Attack, il seguente è sostanzialmente migliore del precedente?

$hashed_password = hash( $pepper . $salt . $password )

dove $salt è memorizzato in testo normale nel database e $pepper è una costante memorizzata in testo normale nel codice dell'applicazione (o configurazione se il codice è utilizzato su più server o l'origine è pubblica).

Aggiungere questo $pepper è facile - stai solo creando una costante nel tuo codice, inserendo un grande valore casuale crittograficamente sicuro (per esempio 32byte da / dev / urandom hex o base64 encoded) in esso, e usando quello costante nella funzione di hashing della password. Se si dispone di utenti esistenti è necessaria una strategia di migrazione, ad esempio rehash della password al successivo accesso e memorizzare un numero di versione della strategia di hashing della password accanto all'hash.

Risposta:

L'utilizzo di $pepper fa aggiunge alla forza della password hash se compromissione del database non implica compromissione dell'applicazione . Senza la conoscenza del pepe, le password rimangono completamente sicure. A causa della specifica password salt non riesci nemmeno a scoprire se due password nel database sono uguali o meno.

Il motivo è che hash($pepper . $salt . $password) crea effettivamente una funzione pseudo casuale con $pepper come chiave e $salt.$password come input (per% sesi con% di candidati come PBKDF2 con SHA *, bcrypt o scrypt). Due delle garanzie di una funzione pseudo casuale sono che non è possibile dedurre l'input dall'output sotto una chiave segreta e né l'output dall'input senza la conoscenza della chiave. Sembra molto simile alla proprietà unidirezionale delle funzioni hash, ma la differenza sta nel fatto che con valori di entropia bassi come le password è possibile enumerare efficacemente tutti i valori possibili e calcolare le immagini sotto la funzione di hash pubblico e quindi trovare il valore di cui l'immagine corrisponde alla pre-immagine. Con una funzione pseudo casuale non puoi farlo senza la chiave (cioè senza il pepe) dato che non puoi nemmeno calcolare l'immagine di un singolo valore senza la chiave.

Il ruolo importante di hash in questa impostazione entra in gioco se si ha accesso al database per un tempo prolungato e si può ancora lavorare normalmente con l'applicazione dall'esterno. Senza $salt puoi impostare la password di un account che controlli con un valore noto $salt e confrontare l'hash con la password di una password sconosciuta $passwordKnown . Come $passwordSecret se e solo se hash($pepper . $passwordKnown)==hash($pepper . $passwordSecret) è possibile confrontare una password sconosciuta rispetto a qualsiasi valore scelto (come tecnicità presumo resistenza alla collisione della funzione hash). Ma con il sale si ottiene $passwordKnown==$passwordSecret se e solo se hash($pepper . $salt1 . $passwordKnown)==hash($pepper . $salt2 . $passwordSecret) e come $salt1 . $passwordKnown == $salt2 . $passwordSecret e $salt1 sono stati scelti casualmente per $salt2 e rispettivamente $passwordKnown i sali non saranno mai uguali (assumendo valori random sufficientemente ampi come 256 bit) e quindi non è più possibile confrontare le password l'una con l'altra.

    
risposta data 10.07.2018 - 00:48
fonte
88

(Nota: l'uso di un sale è solo metà del lavoro, inoltre è necessario rendere la funzione hash lenta, in modo che l'attacco a una singola password a bassa entropia sia ancora difficile.La lentezza si ottiene solitamente attraverso più iterazioni o hashing la concatenazione di 10000 copie di sale e password.)

Ciò che fa il tuo "pepe" è che trasforma l'hash in un MAC . Creare un MAC sicuro e sicuro con una funzione hash non è semplice, quindi è meglio usare HMAC anziché un prodotto fatto in casa costrutto (il modo teorico per dirlo è che una funzione hash resistente alle collisioni non è necessariamente indistinguibile da un oracolo casuale).

Con un MAC, potrebbe ottenere una certa sicurezza nel seguente senso: probabilmente, l'accesso in lettura al database da parte dell'aggressore potrebbe cessare di essere un problema reale. Il tasto MAC (il "pepe") può concentrare la necessità di riservatezza. Tuttavia, questo si basa sul fatto che il MAC è anche una funzione unidirezionale, che è una proprietà che si otterrà da molte costruzioni MAC (incluso l'HMAC) ma che non è realmente garantita dal punto di vista crittografico (ci sono sottigliezze).

Il "pepe" implica che hai una chiave da gestire, compresa la memorizzazione sicura in un modo che resiste al riavvio. Una chiave è piccola e si adatta alla RAM, ma, a causa dei requisiti di archiviazione, non è chiaro se in realtà migliora la sicurezza. Un utente malintenzionato in grado di leggere l'intero database di solito può anche leggere l'intero disco rigido, incluso qualsiasi file "protetto". Le dimensioni ridotte della chiave possono consentire alcune impostazioni avanzate, ad es. la chiave viene memorizzata su smartcard che vengono utilizzate in fase di avvio ma non lasciate successivamente connesse. Per riassumere, se il peppering vale lo sforzo dipende completamente dal contesto: su base generale, lo consiglierei contro di esso, al fine di evitare la complessità aggiuntiva.

    
risposta data 22.04.2011 - 16:53
fonte
25

Vorrei sottolineare cosa può davvero fare un peperoncino.

Quando aiuta un peperoncino?

Come già sottolineato dagli altri, l'aggiunta di un pepe è solo un vantaggio, purché l'autore dell'attacco abbia accesso ai valori hash nel database, ma non ha alcun controllo sul server, e quindi non lo sa il pepe . Questo è tipico per SQL-injection, probabilmente uno degli attacchi più usati, perché è così facile da fare.

Che cosa migliora un peperone?

$hashValue = bcrypt('12345', $cost, $salt);

Questa password si può ottenere facilmente con un attacco di dizionario, anche se hai usato correttamente una funzione di derivazione a chiave lenta. Inserisci le password più utilizzate in un dizionario e forza bruta con queste password deboli. È molto probabile che troviamo la password in (anche) molti casi.

$hashValue = bcrypt('12345anm8e3M-83*2cQ1mlZaU', $cost, $salt);

Con il pepe, la password debole aumenta di lunghezza, contiene ora caratteri speciali e, cosa più importante, non la troverai in nessun dizionario. Quindi, finché il pepe rimane segreto, previene gli attacchi di dizionario , in questo caso può proteggere le password deboli.

Modifica:

C'è un modo migliore per aggiungere una chiave lato server, piuttosto che usarla come pepe. Con un pepe, un utente malintenzionato deve ottenere privilegi aggiuntivi sul server per ottenere la chiave. Lo stesso vantaggio che otteniamo calcolando prima l'hash e successivamente crittografando l'hash con la chiave lato server (crittografia bidirezionale). Questo ci dà la possibilità di scambiare la chiave ogni volta che è necessario.

$hash = bcrypt($passwort, $salt);
$encryptedHash = encrypt($hash, $serverSideKey);
    
risposta data 02.11.2012 - 16:52
fonte
9

Il documento sull'invenzione della salatura e delle iterazioni, per le password Unix ( Password Security: A Case History, Morris & Thompson, 1978 ), ha anche descritto l'equivalente di un pepe:

The first eight characters of the user’s password are used as a key for the DES; then the algorithm is used to encrypt a constant. Although this constant is zero at the moment, it is easily accessible and can be made installation-dependent.

Non ne ho mai sentito parlare. Qualcun altro?

    
risposta data 10.05.2011 - 07:21
fonte
7

Solo una BTW, la nuova NIST Digital Idendity Guidelines (Draft) consiglia vivamente di usare Pepper pure:

link

5.1.1.2 Verificatore di segreti memorizzati:

... A keyed hash function (e.g., HMAC [FIPS198-1]), with the key stored separately from the hashed authenticators (e.g., in a hardware security module) SHOULD be used to further resist dictionary attacks against the stored hashed authenticators.

    
risposta data 06.05.2017 - 20:08
fonte
4

Considera questo scenario:

Sto per entrare in un sito Web X utilizzando un'iniezione SQL per recuperare un elenco di utenti, con i loro hash password e salt. Supponiamo che il sito X utilizzi anche un peperone globale.

Tutto quello che dovrei fare sarebbe registrare un utente sul sito X con un nome utente e una password a me noti prima dell'iniezione SQL. Vorrei quindi sapere, per un particolare record nel database, l'hash della password, la password di testo in chiaro, il sale (memorizzato come testo normale) e sarebbe computazionalmente banale da parte mia per rompere il pepe globale sulla base di questo record .

Quindi, un pepe sarebbe un modo per rallentare un attaccante per una quantità insignificante di tempo di overhead. Non avrebbero dovuto forzare la password + sale + pepe, come previsto, solo il pepe.

Quanto sopra è una forma di attacco di testo in chiaro scelto . Finché gli hacker conoscono l'algoritmo (hash ()), l'output ($ hashed_password) e tutti tranne uno degli input ("costanti" $ salt & $ password e "variabile" $ pepe), possono "risolvere per x "come un'equazione di algebra lineare (h = s + p + x == hsp = x), ma naturalmente con la forza bruta. Rendere il pepe più lungo di 56 byte (448 bit), il limite di bcrypt, aumenta il costo del tempo ed è buono come bcrypt ma potrebbe non essere buono come scrypt. Quindi, finché il pepe è sufficientemente lungo, è un miglioramento.

    
risposta data 31.08.2013 - 08:20
fonte
1

Non ho molta familiarità con il modo in cui un server sarebbe in grado di nascondere una costante di pepe globale ma la mia opinione è che prima o poi un hacker che è penetrato nel server capirà come catturare il valore del pepe. Per rendere totalmente sicuro un valore di pepe, sarebbe necessario un hardware speciale. Un modo per farlo sarebbe quello di utilizzare una scheda FPGA installata nel server. L'FPGA conterrebbe il codice utilizzato per eseguire l'hash incluso il valore del pepe e tutti i calcoli di hash si verificano all'interno dell'FPGA. Con l'FPGA, la programmazione può essere una funzione unidirezionale. Il pepe può essere programmato ma non ci sono istruzioni che possono essere inviate per leggerlo di nuovo. Il peperone sarebbe stato conservato su un pezzo di carta chiuso in una cassastrong. Se il pepe è 128+ bit generati casualmente, non ci sarebbe alcun modo pratico per determinarlo.
Non sei sicuro di quanto sarebbe pratico in quanto aumenterebbe il costo dell'hardware del server.

    
risposta data 07.09.2014 - 20:04
fonte

Leggi altre domande sui tag