it-swarm.dev

Generazione di un token non indovinabile per e-mail di conferma

Sto generando un token da utilizzare quando si fa clic sul collegamento in un'e-mail di verifica. Ho intenzione di utilizzare niqid () ma l'output sarà prevedibile consentendo a un utente malintenzionato di ignorare le e-mail di conferma. La mia soluzione è l'hash. Ma non è ancora abbastanza perché se viene scoperto l'hash che sto usando, sarà comunque prevedibile. La soluzione è salarla. Che non sono sicuro di come fare perché se uso una funzione per dare salt variabile (ad esempio in pseudocodice hash(uniqid()+time())), allora l'unicità dell'hash non è più garantita? Dovrei usare un hash costante e sarebbe abbastanza buono (ad esempio hash(uniqid()+asd741))

Penso che tutte le risposte manchino un punto importante. Deve essere unico. Cosa succede se openssl_random_pseudo_bytes() proclama lo stesso numero due volte? Quindi un utente non sarebbe in grado di attivare il suo account. La contro argomentazione delle persone è improbabile che produca lo stesso numero due volte? Ecco perché stavo prendendo in considerazione uniqid() perché il suo output è unico.

Immagino che potrei usare entrambi e aggiungerli insieme.

13
Celeritas

Vuoi casualità indiscutibile. Quindi, usa casualità indiscutibile. Usa openssl_random_pseudo_bytes() che si collegherà al locale PRNG crittograficamente forte . Non utilizzare Rand() o mt_Rand() , poiché sono prevedibili (mt_Rand() is statisticamente buono ma non regge contro gli attaccanti senzienti). Non scendere a compromessi, usa un buon PRNG. Non non provare a creare qualcosa da solo lanciando la funzione hash e simili; solo il dolore sta alla fine di questo percorso.

Genera 16 byte, quindi codificali in una stringa se hai bisogno di una stringa. bin2hex() codifica in esadecimale; 16 byte diventano 32 caratteri. base64_encode() codifica in Base64; 16 byte diventano 24 caratteri (gli ultimi due dei quali sono segni "=").

16 byte sono 128 bit, questo è il "valore sicuro" che rende le collisioni così assolutamente improbabili che non devi preoccuparti di loro. Non andare al di sotto di questo a meno che tu non abbia una buona ragione (e, anche in questo caso, non scendere comunque al di sotto dei 16).

25
Tom Leek

Assicurati di avere supporto OpenSSL e non sbaglierai mai con questo one-liner

$token = bin2hex(openssl_random_pseudo_bytes(16));
18
Adi

In PHP 7, puoi semplicemente usare random_bytes :

Genera una stringa di lunghezza arbitraria di byte casuali crittografici adatti per l'uso crittografico, ad esempio durante la generazione di sali, chiavi o vettori di inizializzazione.

Quindi per generare un token esadecimale a 16 byte devi fare:

$token = bin2hex(random_bytes(16));

Formalmente, non vi è alcuna garanzia che tutti i numeri saranno univoci. Ma è improbabile che una collisione accada che ti conviene preoccuparti di essere colpito da una meterorite.

1
Anders