Quale tipo / lunghezza di colonna dovrei usare per memorizzare una password hash di Bcrypt in un database?

Voglio memorizzare una password con hash (usando BCrypt) in un database. Quale sarebbe un buon tipo per questo, e quale sarebbe la lunghezza corretta? Le password sono state sostituite con BCrypt sempre della stessa lunghezza?

MODIFICARE

Hash di esempio:

$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu

Dopo aver cancellato alcune password, sembra che BCrypt generi sempre 60 caratteri di hash.

MODIFICA 2

Ci scusiamo per non aver menzionato l’implementazione. Sto usando jBCrypt .

Il formato di criptazione modulare per bcrypt è composto da

  • $2$ , $2a$ o $2y$ identificano l’ algoritmo di hash e il formato
  • un valore a due cifre che indica il parametro di costo, seguito da $
  • un valore codificato in base 64 a 64 caratteri (usano l’alfabeto . , / , 09 , AZ , az che è diverso dall’alfabeto standard di codifica Base 64 ) composto da:
    • 22 caratteri di sale (effettivamente solo 128 bit dei 132 bit decodificati)
    • 31 caratteri di output crittografato (effettivamente solo 184 bit dei 186 bit decodificati)

Quindi la lunghezza totale è rispettivamente di 59 o 60 byte.

Usando il formato 2a, avrai bisogno di 60 byte. E quindi per MySQL raccomanderò di usare il CHAR(60) BINARY o BINARY(60) (vedi The _bin e binary Collations per informazioni sulla differenza).

CHAR non è binario sicuro e l’uguaglianza non dipende esclusivamente dal valore del byte ma dal confronto effettivo; nel caso peggiore A viene trattato come uguale a a . Vedi le _bin e le _bin binary per maggiori informazioni.

Un hash Bcrypt può essere memorizzato in una colonna BINARY(40) .

BINARY(60) , come suggeriscono le altre risposte, è la scelta più semplice e naturale, ma se si desidera massimizzare l’efficienza dello storage, è ansible salvare 20 byte decostruendo senza perdita l’hash. Ho documentato questo più approfonditamente su GitHub: https://github.com/ademarre/binary-mcf

Gli hash Bcrypt seguono una struttura denominata MCD (modular crypt format). Binary MCF (BMCF) decodifica queste rappresentazioni di hash testuali in una struttura binaria più compatta. Nel caso di Bcrypt, l’hash binario risultante è 40 byte.

Gumbo ha fatto un buon lavoro nel spiegare i quattro componenti di un hash MCcr di Bcrypt:

 $$$ 

La decodifica in BMCF va così:

  1. $$ può essere rappresentato in 3 bit.
  2. $ , 04-31, può essere rappresentato in 5 bit. Metti questi insieme per 1 byte.
  3. Il valore di 22 caratteri è una rappresentazione (non standard) di base 64 di 128 bit. La decodifica Base-64 produce 16 byte.
  4. L’hash digest a 31 caratteri può essere decodificato in base 64 a 23 byte.
  5. Metti tutto insieme per 40 byte: 1 + 16 + 23

Puoi leggere di più al link sopra, o esaminare la mia implementazione PHP , anche su GitHub.

Se stai usando il PHP password_hash() con l’algoritmo PASSWORD_DEFAULT per generare l’hash bcrypt (che suppongo sia una grande percentuale di persone che leggono questa domanda) assicurati di tenere presente che in futuro password_hash() potrebbe usare un algoritmo diverso come predefinito e questo potrebbe quindi influenzare la lunghezza dell’hash (ma potrebbe non essere necessariamente più lungo).

Dalla pagina di manuale:

Si noti che questa costante è progettata per cambiare nel tempo man mano che nuovi e più potenti algoritmi vengono aggiunti a PHP. Per questo motivo, la lunghezza del risultato dell’utilizzo di questo identificatore può cambiare nel tempo. Pertanto, si consiglia di archiviare il risultato in una colonna del database che può espandersi oltre i 60 caratteri (255 caratteri sarebbero una buona scelta).

Usando bcrypt, anche se hai 1 miliardo di utenti (cioè sei attualmente in concorrenza con Facebook) per archiviare gli hash delle password a 255 byte, basterebbero solo ~ 255 GB di dati, circa le dimensioni di un disco rigido SSD piuttosto piccolo. È estremamente improbabile che l’archiviazione dell’hash della password costituisca il collo di bottiglia nell’applicazione. Tuttavia, nel caso in cui lo spazio di archiviazione sia davvero un problema per qualche motivo, è ansible utilizzare PASSWORD_BCRYPT per forzare password_hash() per utilizzare bcrypt, anche se non è quello predefinito. Basta essere sicuri di essere informati su eventuali vulnerabilità presenti in bcrypt e rivedere le note di rilascio ogni volta che viene rilasciata una nuova versione di PHP. Se l’algoritmo predefinito viene mai modificato, sarebbe opportuno esaminare perché e prendere una decisione informata sull’utilizzo del nuovo algoritmo o meno.

Non penso che ci siano trucchi netti che è ansible archiviare come si può fare, ad esempio con un hash MD5.

Penso che la cosa migliore da fare sia memorizzarla come CHAR(60) dato che è sempre lunga 60 caratteri