2010-03-25 14 views
12

Qual è il modo migliore per generare in modo crittografato un massimo di 32 byte in PHP, senza dipendere dalle librerie incluse raramente nelle tipiche installazioni di PHP?Generazione di sale in PHP

Dopo aver cercato su Google ho scoperto che mt_rand non è considerato abbastanza sicuro, ma non ho trovato un suggerimento per una sostituzione. Un articolo ha suggerito la lettura dal /dev/random ma non solo questo non funzionerà su Windows; è anche molto lento.

Voglio un ragionevole equilibrio tra la sicurezza e la velocità (cioè, non dovrebbe prendere 20 secondi per generare 512 byte, come /dev/random fa di solito)

+2

'/ dev/urandom' può essere utilizzato per una generazione più veloce, ma non funzionerà sui sistemi Windows. – Amber

risposta

7

Nota: mcrypt è stato deprecato in PHP 7.1. Skip to the up-to-date answer.

Si consiglia di dare un'occhiata alla documentazione (e commenti) per mcrypt_create_iv().

+1

mcrypt è obsoleto in PHP 7.1. Non dovresti scrivere codice che è già deprecato. Quindi se leggi questo nel 2016, non usare questa risposta, preferisci quella di @Scott Arciszewski. – JesusTheHun

-9

Credo microtime() è sufficiente.

Stranamente, ma sto ancora ottenendo downvotes per questa risposta.

Anche se l'unica spiegazione che ottengo è che il microtime è prevedibile.
Mi sembra strano come sale sempre assunto come conosciuto apertamente - quindi, non serve affatto per la previsione.

+1

Non proprio. Non solo è molto facile da prevedere (è l'ora corrente), ma non posso nemmeno ricavarne 32 byte. – qster

+4

@qster puoi usarlo come generatore di numeri casuali. E ottieni un numero qualsiasi di byte che vuoi. E non è l'ora attuale, l'hai incasinato con il tempo(). I microsecondi cambiano abbastanza velocemente. Ed è solo salato, non hai bisogno di troppa sicurezza sul sale. –

+0

@YourCommonSense Esegui 'echo microtime()' attraverso un ciclo for (10 loop va bene) e vedi quanto sei sbagliato ... –

-3

uniqid() dovrebbe andare bene per questo scopo.

+1

Uso anche uniqid() con un valore di seme calcolabile veloce (come il microtime suggerito). Non ho fatto un'analisi crittografica, ma sembra adattarsi alla legge. – Boldewyn

0

Leggere da /dev/urandom o utilizzare openssl_random_pseudo_bytes().

7

Nota: mcrypt è stato deprecato in PHP 7.1. Skip to the up-to-date answer.

È possibile utilizzare la funzione mycrypt_create_iv(), poiché la versione 5.3 di PHP utilizza anche la fonte casuale su un server Windows (non solo su Unix). Prima di usarlo, è necessario verificare se è definita la costante MCRYPT_DEV_URANDOM.

mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); 

differenza casuale, urandom Non blocca il server, se non c'è abbastanza entropia disponibili. Dal momento che la password sale dovrebbe essere unica (non necessariamente casuale), l'urandom sembra essere una buona scelta per me.

+0

Si noti che il secondo argomento è facoltativo e il valore "MCRYPT_DEV_URANDOM' è il valore predefinito - quindi se non si vuole cambiarlo, si può anche fare" mcrypt_create_iv ($ length) ". Inoltre, questa funzione è implementata nell'estensione 'mcrypt' che può o non può essere installata sul tuo server. Infine, il risultato di tale funzione è una stringa binaria che spesso non è ciò di cui hai bisogno, dato che vuoi salvare il sale per il riferimento successivo. Solitamente 'base64_encode' il risultato prima di usarlo come sale. – Guss

+0

@Guss - Questi sono buoni punti. Inoltre bisogna controllare, in quale forma è previsto il sale. BCrypt ad esempio non accetterà un binario salt, ma un sale codificato in base64 non è valido neanche. Per l'hashing della password è meglio usare la funzione incorporata [password_hash()] (http://www.php.net/manual/en/function.password-hash.php), che genera un sale sicuro da solo. – martinstoeckli

+0

Un motivo per non usare 'password_hash()' è che non sto implementando una password. Ho bisogno di un sale per implementare un protocollo di autorizzazione in stile "api chiave" senza stato. – Guss

2

uniqueid non è adatto per la generazione di una stringa casuale in quanto anch'essa è basata su microtime. Un ciclo CPU è generalmente molto più breve di un tick microtime, il che può portare a una possibile costanza per una data variabile all'interno di loop. Impostazione del secondo parametro "entropia" true,

uniqid('', true) 

fornirà maggiore casualità.

Per ottenere una stringa casuale che è ben compatibile con la maggior parte dei caratteri-set, si può applicare la codifica base64 al mcrypt initilization funzione vettoriale mcrypt_create_iv:

$length = 16; 
base64_encode(mcrypt_create_iv(ceil(0.75*$length), MCRYPT_DEV_URANDOM)) 
//> hlZuRJypdHFQPtI2oSFrgA== 
strlen(base64_encode(mcrypt_create_iv(ceil(0.75*$length), MCRYPT_DEV_URANDOM))) 
//> 16 

Ridurre il carattere dell'alfabeto a 2^6bit aumenta la dimensione, che è rappresentata sopra.