Usare SHA-256 per pre-processare la password prima di bcrypt?

20

Vorrei consentire agli utenti della mia applicazione Web di avere password lunghe, se lo desiderano. Oggi sono venuto a conoscenza della limitazione della lunghezza della password di bcrypt (72 caratteri, il resto troncato).

Sarebbe sicuro per me fare quanto segue? Sto usando PHP.

Implementazione corrente:

password_hash($password, PASSWORD_BCRYPT, $options);

Implementazione in questione:

password_hash(hash('sha256', $password), PASSWORD_BCRYPT, $option);

Quali sono gli svantaggi dell'implementazione in questione?

Non sono un esperto di crittografia, per favore consiglio.

L'implementazione in questione limiterà la lunghezza della password che un utente può utilizzare? Se sì, quale sarà il limite?

    
posta Jay 14.02.2017 - 10:36
fonte

3 risposte

24

In generale, questo andrà bene. È anche un metodo abbastanza consigliato per consentire password di lunghezza arbitraria in bcrypt.

Matematicamente, stai usando bcrypt su una stringa di 64 caratteri, dove ci sono 2 ^ 256 possibili valori (SHA-256 fornisce output a 256 bit, che viene comunemente rappresentato come una stringa esadecimale di 64 caratteri). Anche se qualcuno ha precalcolato le password comuni in SHA-256, avrebbe dovuto eseguirle attraverso bcrypt per trovare quale fosse l'input effettivo per un determinato hash.

Il principale svantaggio potenziale sono i difetti di implementazione: se si memorizzano i valori SHA-256, sono relativamente veloci da interrompere, quindi un utente malintenzionato non dovrebbe impiegare lo sforzo per rompere i valori di bcrypt.

Si raccomanda comunque di mantenere un conteggio iterativo abbastanza alto per il passo bcrypt: questo non dovrebbe avere alcun effetto particolarmente dannoso sul tempo di elaborazione, ma rende gli attacchi brute force molto più difficili.

Vedi Pre-hash password prima di applicare bcrypt per evitare di limitare la lunghezza della password per il caso generale.

    
risposta data 14.02.2017 - 10:46
fonte
11

La tua implementazione suggerita è sicura. Tuttavia, fai attenzione a documentare il tuo uso speciale della funzione.

Tieni presente che password_hash troncherà la password al primo byte NULL, quindi NON devi utilizzare l'opzione $raw_output=true della funzione hash .

    
risposta data 14.02.2017 - 10:53
fonte
4

Non farlo, stai limitando la tua forza chiave a molto meno di ciò che bcrypt da solo può accettare.

Utilizza invece questo approccio (pseudo-codice non valido PHP):

if length($password) > 72 bytes
then
    $hash = sha256($password)
    $password = concat(substring($password, 320 bits), base255encode($hash))
end if
bcrypt($password)

In questo modo, le password tra 256 e 576 bit mantengono la loro piena entropia e le password di oltre 576 bit usano non solo i 256 bit dell'hash, ma la maggior parte dell'entropia originale che può stare insieme all'hash.

È discutibile se l'hash debba essere fatto attraverso l'intera password, o solo la porzione oltre i 320 bit sostituiti dall'hash. Dubito seriamente che faccia la differenza quando hai scelto un hash crittografico con buone proprietà.

Il passo base255encode evita di avere un byte NUL che termina il tasto in anticipo, come avvertito da @ a-hersean.

    
risposta data 14.02.2017 - 21:10
fonte