Argomenti che dimostrano lo schema di hashing è sufficiente

3

Attualmente stiamo lavorando su una nuova applicazione server che sta per comunicare con le applicazioni client su molti sistemi diversi. Per questo abbiamo voluto implementare un nuovo schema di hashing delle password.

Ho svolto alcune ricerche, inclusa la lettura di molte domande su security.SE e crypto.SE, sull'hashing delle password. Dopo questa ricerca sono arrivato al seguente schema di hashing:

Utilizzeremo PBKDF2 come algoritmo di hashing. La scelta per questo risiede principalmente nel fatto che sia disponibile direttamente in .NET Framework. Ho esaminato sia bcrypt che scrypt , ma poiché entrambi hanno bisogno di librerie di terze parti, siamo andati con PBKDF2 .

Con l'uso di PBKDF2 c'è anche il sale libero che ottieni quando generi un hash per la prima volta.

La domanda quindi era come salvare i dati nel database. Avevamo due opzioni:

  • Salva ciascun valore separatamente, ad esempio hash, salt, iterations e algoritmo.
  • O salvalo come una singola stringa.

Siamo andati con il valore della singola stringa che appare come segue:

<algorithm>$<iterations>$<salt>$<hash>

Questo è simile a come, ad esempio, Django lo fa.

L'ho implementato in questo modo e ho scritto una relazione con le nostre scelte e argomenti. Ma ora ho domande sul design. Per esempio alcuni si chiedono perché il sale sia così chiaramente salvato, non sarebbe meglio combinare il sale e l'hash in una singola stringa per renderlo meno ovvio agli aggressori.

Di solito questi casi fanno presupposizioni in cui gli utenti malintenzionati hanno solo il database e così via. Mentre sostengo che dovremmo sempre considerare lo scenario peggiore e assumere che gli hacker abbiano sia il codice che il database. Sostengo anche che il sale è lì per annullare l'effetto delle tabelle arcobaleno e tabelle di ricerca. E il numero di iterazioni è l'attacco di forza bruta deterrente.

Ma poiché non sono un professionista della sicurezza, quello che dico può essere facilmente ignorato (anche se questo vale per qualsiasi argomento su Internet;)).

Pertanto, ho bisogno di tutto ciò che può dimostrare che ciò che abbiamo creato è un modo corretto di farlo.

Ho appena implementato un sacco di cose che ho trovato su internet, ma non ho alcuna prova (scientifica) che sia sufficiente.

    
posta Chrono 20.02.2013 - 16:49
fonte

3 risposte

5

Il sale non deve essere segreto, perché se avesse bisogno di essere segreto lo chiameremmo un chiave .

Fare le cose correttamente e convincere altre persone che hai fatto le cose correttamente, sono due problemi distinti. In ogni caso, assumiamo sempre che l'hacker conosca sia il contenuto del database sia il codice, perché è ciò che accade nella pratica. Mantenere il codice segreto è molto difficile, poiché esiste come binari e codici sorgente in molti luoghi (il server stesso, le macchine degli sviluppatori, i nastri di backup, i teste degli sviluppatori, e probabilmente su tutto l'Internet se il codice è opensource). Supponendo che il codice sia segreto non sembra essere una buona base per la sicurezza.

Pertanto, si può (e si deve) assumere che l'attaccante saprà quale parte della stringa memorizzata è la salt e quale parte è il valore hash. Quindi, puoi anche usare una codifica chiara e precisa, come suggerisci tu.

Per la parte convincente , cita il NIST (l'organizzazione federale statunitense che si occupa, in particolare, degli standard di crittografia), pubblicazione speciale 800-132 . Si veda ad esempio la pagina 3 di quel documento, dove il sale è definito come:

A non-secret binary value that is used as an input to the key derivation function PBKDF specified in this Recommendation to allow the generation of a large set of keys for a given password.

(enfasi su "non segreto").

    
risposta data 20.02.2013 - 20:30
fonte
2

Aggiungere semplicemente il sale all'hash piuttosto che visualizzarlo in modo chiaro è efficacemente protetto dall'oscurità e aggiunge un valore minimo, ma l'altra domanda è, c'è qualche ragione per non farlo. Se sai come analizzarlo, allora è banale, ma è formattato, quindi non c'è nulla di negativo nell'averlo direttamente concatenato.

Detto questo, se c'è un potenziale che l'algoritmo o la lunghezza potrebbero cambiare in futuro, avere un campo a larghezza fissa sarebbe negativo. Poiché stai anche memorizzando l'algoritmo utilizzato, questa è forse una buona ragione per non concatenare semplicemente i valori. In ogni caso, non vi è una reale implicazione della sicurezza per spiegare che un valore particolare è il sale contro il tentativo di offuscarlo. La segretezza di sale non è richiesta per la sicurezza del sistema.

    
risposta data 20.02.2013 - 17:16
fonte
0

È necessario memorizzare tutte queste informazioni (algoritmo, iterazioni, sale, hash) per ogni utente singolarmente, quindi deve essere nel database. Il sale deve essere unico per ogni utente. Mentre molte voci avranno lo stesso algoritmo e il numero di iterazioni, nel tempo non ci sarà un singolo valore per tutti gli utenti. Il motivo è che con il passare del tempo, vorrai aumentare il numero di iterazioni (ogni volta che aggiorni il tuo server), e occasionalmente cambiare l'algoritmo (ad esempio, passare a scrutare se una nuova versione di .NET lo offre). Ma puoi farlo solo quando un utente effettua il login, perché hai bisogno della stringa della password originale per creare il nuovo hash. Poiché ciò è imprevedibile, quando un utente effettua l'autenticazione, è necessario recuperare l'algoritmo, il conteggio dell'iterazione e il sale, utilizzare questi più la password immessa dall'utente per calcolare l'hash e confrontare l'hash con l'hash di riferimento memorizzato nel database. Quindi devi essere in grado di analizzare tutti questi campi.

La sicurezza dell'archiviazione delle password non si basa sul significato che i campi sono oscuri per gli aggressori. Solitamente, l'utente malintenzionato sa come funziona l'applicazione (potrebbe essere in esecuzione l'applicazione su un server di prova o addirittura avere il codice sorgente). Anche per un'applicazione interna, l'autore dell'attacco potrebbe aver creato alcuni account e provare facilmente varie combinazioni.

"Rendilo meno ovvio agli aggressori" è molto chiaramente sicurezza attraverso l'oscurità . È come mettere la testa nella sabbia e assumere che il tuo attaccante faccia lo stesso. Non è assolutamente necessario nascondere le informazioni che sono irrilevanti per la sicurezza del sistema.

D'altra parte, ci sono rischi e costi associati a non disporre chiaramente i campi. Nel tempo, dovrai mantenere la tua applicazione, forse a un certo punto dovrai riscrivere il modulo di autenticazione. Più semplice è il modo in cui codifichi, più facile sarà la manutenzione. Seguire uno schema standard è una buona idea (gli schemi separati dal dollaro non sono specifici per Django). L'utilizzo di una complessa codifica interna aumenta il rischio di sbagliare, con conseguente hash delle password illeggibili o, al contrario, in hash troncati facilmente interrotti.

    
risposta data 20.02.2013 - 20:08
fonte

Leggi altre domande sui tag