Il tuo sale non ha bisogno di essere perfettamente casuale, deve solo essere unico per ciascuno dei tuoi utenti. Vedi questa domanda su Crypto.SE per di più. Ecco perché alcuni siti web usano il nome utente per ricavare il sale da (cioè $salt=$username.$signup_date
).
Nel tuo caso, quando cripta dice "blowfish hash" significa veramente bcrypt così vuoi anche tenere il passo con la legge di Moore quando selezioni il fattore di costo.
Ci sono alcune osservazioni che ho fatto sul tuo codice però. Innanzitutto, strlen()
non include il carattere NULL alla fine, quindi strlen($blowfishCharacters) - 1;
ti assicura che tu sia " Non vedrò mai un /
nel tuo sale. Suggerisco anche di utilizzare range()
durante la creazione dell'array, ma questa è la mia preferenza personale. Puoi anche eliminare completamente il ciclo poiché non ci piace reinventare la ruota (giusto?). Pertanto il tuo codice ora si presenta così:
$salt=array_merge(range('a', 'z'), range('A', 'Z'), ['.', '/']); //generate the dictionary
shuffle($salt);
$salt=array_slice($salt, 0, 21); //cut to size
Questo restituirà una matrice $salt
con 21 elementi. Il 22esimo elemento richiesto da crypt
è in realtà il delimitatore $
.
Per rispondere alla tua domanda originale: in base alla pagina man di mt_rand()
By default, PHP uses the libc random number generator with the rand() function. The mt_rand() function is a drop-in replacement for this. It uses a random number generator with known characteristics using the » Mersenne Twister, which will produce random numbers four times faster than what the average libc rand() provides.
quindi non è più "sicuro" ma funziona più velocemente.
In conclusione, non hai bisogno di un PRF di tipo crypto-grade per ricavare il sale da. Questo perché un sale protegge da tabelle hash pre-calcolate. Se non si dispone di un sale, l'avversario può pre-generare una tabella e confrontarla con l'intero database per trovare una corrispondenza. Il sale fa sì che l'avversario debba eseguire quel processo per ogni voce nel database, rendendo così l'attacco estremamente costoso con un fattore di costo sufficientemente elevato.
Naturalmente l'impostazione del costo troppo alto renderà il tuo server in difficoltà quando molti utenti tenteranno di accedere allo stesso tempo, ma rischierei di scomodare la sicurezza in qualsiasi momento.
Quindi la risposta alla tua domanda è yes mt_rand()
è abbastanza buono .
Modifica: questo articolo è una buona guida per l'igiene di bcrypt. Citando la sezione # 2,
A perfect source would be /dev/urandom. Other sources would be mcrypt_create_iv when paired with MCRYPT_DEV_URANDOM. If neither of them are available, you can fall back to openssl_random_pseudo_bytes or mt_rand (at an absolute last resort).
quindi usa mcrypt_create_iv
invece .