Una pulizia del tuo codice
Questo è lo stesso di quello che stai facendo, ma scritto in modo un po 'più elegante:
function random_str()
{
$secret = '';
while(strlen($secret) >= 20) {
$str = bin2hex(random_bytes(10));
$str = preg_replace('/[aeiouAEIOU]|\W+/', '', sha1(microtime() . mt_rand() . $str));
$secret .= $str;
}
return substr($secret, 0, 20);
}
Avviso Ho rimosso la variabile $i
inutile. (Lo so, non un problema di sicurezza, ma comunque.)
È sicuro?
Il codice è molto contorto e prende un percorso piuttosto strano per risolvere un problema non così difficile. Alcuni problemi:
- Usi l'hash
sha1(microtime() . mt_rand() . $str)
quando basti solo su $str
sarebbe sufficiente. Ecco dove si ottiene l'input da un CSPRNG. Aggiungendo un po 'di casualità non sicura ( mt_rand
) e il tempo e poi l'hashing non lo migliora.
- Poiché rimuovi le vocali da una stringa esadecimale, finisci per utilizzare solo il carattere
0123456789bcdf
. Quello è solo quattordici - non molto.
- È un po 'strano generare per prima cosa una stringa contenente caratteri che non vuoi e poi buttarli via, quando puoi generare solo quelli che vuoi.
Alla fine, il risultato è crittograficamente sicuro, poiché si basa su random_bytes()
, questo è un CSPRNG. Ma le peculiarità del tuo codice e la tua mancanza di comprensione portano all'insicurezza, ad es. in questo caso potresti finire con meno entropia per personaggio rispetto a quanto ti saresti aspettato.
Un modo migliore per farlo
Usa la funzione PHP random_int
per scegliere un carattere da un alfabeto fisso a caso :
function random_string($length, $alphabet) {
$result = ''; //Initialize an empty string.
$max = strlen($alphabet) - 1; //The maximum random number we want to generate.
for($i = 0; $i < $length; $i++) { //Do once for every character in the string.
$result .= $alphabet[random_int(0, $max)]; //Add a random letter from the alphabet.
}
return $result;
}
Probabilmente la performance potrebbe essere migliorata eliminando la concatenazione di stringhe nel loop, ma probabilmente non è un grosso problema.