Hash password sicura

Ho bisogno di memorizzare un hash di una singola password in un’applicazione .Net WinForms.

Qual è il modo più sicuro per farlo?

In particolare:

  • Sale, HMAC o entrambi?
  • Quanto sale?
  • Quante iterazioni?
  • Quale codifica? (La password è semplice ASCII)

Suppongo che l’algoritmo debba essere SHA512 o HMACSHA512.

Sale il tuo hash con sale casuale sicuro di almeno 128 bit o più, per evitare un attacco arcobaleno e usa BCrypt , PBKDF2 o scrypt . PBKDF2 viene fornito con l’ approvazione NIST .

Per citare: Archive.org: http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what- you-need- to- know-about-s.html

Il problema è che MD5 è veloce. Così sono i suoi concorrenti moderni, come SHA1 e SHA256. La velocità è un objective progettuale di un moderno hash sicuro, perché gli hash sono un elemento fondamentale di quasi tutti i sistemi di crittografia e in genere ottengono un’esecuzione su richiesta per pacchetto o per messaggio.

La velocità è esattamente ciò che non si desidera in una funzione di hash della password.

Le funzioni di convalida rapida delle password sono un problema, perché possono essere attaccate usando la forza bruta. Con tutti gli algoritmi sopra puoi controllare la “lentezza”

Posso consigliare BCrypt.net . Molto facile da usare e puoi sintonizzare quanto ci vorrà per fare l’hashing, il che è fantastico!

 // Pass a logRounds parameter to GenerateSalt to explicitly specify the // amount of resources required to check the password. The work factor // increases exponentially, so each increment is twice as much work. If // omitted, a default of 10 is used. string hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12)); // Check the password. bool matches = BCrypt.CheckPassword(candidate, hashed); 

Per un’implementazione lato server con un numero elevato di password, è necessario utilizzare un approccio sintonizzabile iterato come bcrypt. Questo noto articolo sull’argomento è ancora (principalmente) pertinente:

http://www.securityfocus.com/blogs/262

Per una singola password in un’applicazione stand-alone, in cui il percorso di archiviazione è probabilmente già protetto dal sistema di autenticazione del sistema, penso che sia molto meno importante. Un singolo hash forte è probabilmente abbastanza buono, e l’aggiunta di sale è abbastanza facile che non c’è ragione per non farlo.

RNGCryptoServiceProvider per generare un salt casuale, quindi SHA512 la password con il sale, e infine memorizzare sia l’hash della password che il sale corrispondente se si desidera verificare in seguito che il testo sia uguale alla password memorizzata.

Hash e Salt. Se hai solo hash potresti essere attaccato da un attacco arcobaleno (reverse ha lookup) e un sale lo rende molto più difficile (il sale casuale sarebbe il migliore). Per la tua codifica vorrai sia Base64 che Hex codificare il tuo byte array risultante . Se si tenta di archiviare l’array di byte come Unicode, si rischia di perdere alcuni dati perché non tutti i pattern sono caratteri validi. Ciò consente anche un modo più semplice per confrontare gli hash (basta confrontare la base64 o la stringa esadecimale quando si desidera validare invece di confrontare l’array di byte)

Un numero maggiore di round non fa molto oltre il rallentamento sarebbe attaccante. Ma è anche molto più difficile riutilizzare gli hash in futuro se si perde o si ha bisogno di ricreare l’algoritmo di hash. Si potrebbe verificare un hash di password standard come crypt su sistemi unix. Ciò consente di modificare l’algoritmo hash e può anche supportare il controllo delle versioni.

Ma ancora una volta, un semplice hash + sale è abbastanza buono per la maggior parte delle applicazioni.

Rigorosamente guardando più sicuro:

Salt, HMAC, or both?

Entrambi sarebbero più sicuri. Dal momento che la chiave dell’HMAC potrebbe essere considerata salata, fare entrambe le cose sarebbe un po ‘ridondante, ma comunque più sicura perché ci vorrebbe più lavoro da fare.

How much salt?

Ogni bit di sale raddoppierà le combinazioni che dovrebbero essere mantenute in un rainbow-table per rompere facilmente la password. Ma dal momento che esiste una sola password e un solo sale, potrebbe non essere necessario più. HMAC utilizza la dimensione del blocco dell’hash sottostante per le dimensioni della chiave, 1024 bit per SHA512. Le dimensioni del blocco dovrebbero essere abbastanza buone per il sale, ma raddoppiare o triplicare renderebbe molto più difficile craccare la password con un tavolo arcobaleno.

How many iterations?

Più sono e meglio è. Certo, più iterazioni significa che ci vorrà più tempo per determinare se è stata inserita la password corretta, ma i computer sono veloci e gli utenti non si preoccuperanno di attendere qualche secondo durante la verifica della password. Fare più iterazioni significherebbe che qualcuno che infrange la password dovrebbe fare anche altre iterazioni.

What encoding? (The password is plain ASCII)

Potrebbe anche cifrare (con AES) la password over-salted, HMAC, super-sicura, insieme al suo sale solo per renderlo più difficile. Creare la password per l’hash e la chiave crittografati della password, essere una combinazione di stringhe che dovrebbero apparire nell’eseguibile come “RNGCryptoServiceProvider” o “System.Security.Cryptography”. E mentre codifichiamo potremmo anche convertirlo hex, o base64, o meglio ancora base-36 o qualche altra conversione meno attesa.

Nota: questo è stato scritto principalmente per scherzo, ma dovrebbe comunque contenere un po ‘di verità.

Penso che dovresti rispettare standard aperti. Tra gli attuali schemi di hash, il “{ssha}” utilizzato da OpenLDAP è molto sicuro e ampiamente utilizzato. Puoi trovare la descrizione qui,

http://www.openldap.org/faq/data/cache/347.html

La maggior parte delle librerie LDAP implementa questo schema.

Puoi seguire uno standard pubblicato, come pkcs # 5. vedi http://en.wikipedia.org/wiki/PKCS per una breve descrizione o http://tools.ietf.org/html/rfc2898 per la RFC.

Ecco un’API che farà tutto il necessario / vuoi 🙂

https://sourceforge.net/projects/pwdtknet