2013-09-16 11 views
49

Al fine di generare un token 32 caratteri per l'accesso alla nostra API Al momento stiamo utilizzando:Generazione crittograficamente sicuro gettoni

$token = md5(uniqid(mt_rand(), true)); 

Ho letto che questo metodo non è crittograficamente sicuro in quanto si basa su l'orologio di sistema, e che openssl_random_pseudo_bytes sarebbe una soluzione migliore in quanto sarebbe più difficile da prevedere.

Se questo è il caso, quale sarebbe il codice equivalente?

Presumo che qualcosa di simile, ma non so se questo è giusto ...

$token = md5(openssl_random_pseudo_bytes(32)); 

anche che lunghezza ha un senso che io debba passare alla funzione?

+1

Perché md5 però? Basta convertire iltestream in esadecimale: si ottengono 32 byte di ritorno da openssl_random_pseudo_bytes(), il rendering di ciascuno di quei byte come valore esadecimale con bin2hex() come mostrato nel [documento PHP] (http://www.php.net/ manuale/en/function.openssl-random-pseudo-bytes.php) esempi –

+0

Voglio solo 32 caratteri? Come potrei farlo? – fire

+7

'md5()' genera una stringa di 32 caratteri, ma contiene solo un valore di 128 bit di dati. 'openssl_random_pseudo_bytes()' restituisce dati binari veri, quindi ha 32 * 8 = 256 bit di casualità. Riempiendo la tua stringa casuale da 32-byte attraverso md5, stai effettivamente riducendo la sua unicità di una quantità enorme. –

risposta

121

ecco la soluzione giusta:

$token = bin2hex(openssl_random_pseudo_bytes(16)); 

# or in php7 
$token = bin2hex(random_bytes(16)); 
+1

Ho aggiunto un'altra risposta su come è possibile generare un token univoco utilizzando openssl_random_pseudo_bytes con CryptoLib. Questo ti consente di generare token con tutti i personaggi anziché solo 0-9, A-F. – mjsa

+10

Per PHP 7 e versioni successive, usare 'bin2hex (random_bytes ($ length));' – Lionel

+3

Supporto PHP 5.x per random_bytes() e random_int() https://github.com/paragonie/random_compat – MTK

6

Se si dispone di un generatore di numeri casuali protetto da crittografia, non è necessario eseguire l'hash. In realtà tu non vuoi. Basta usare

$token = openssl_random_pseudo_bytes($BYTES,true) 

Dove $ BYTE è comunque molti byte di dati che si desidera. MD5 ha un hash a 128 bit, quindi faranno 16 byte.

Come nota a margine, nessuna delle funzioni chiamate nel codice originale è crittograficamente sicura, la maggior parte sono dannose abbastanza che l'utilizzo di una sola interruzione potrebbe risultare non sicuro anche se combinato con altre funzioni sicure. MD5 ha problemi di sicurezza (anche se per questa applicazione potrebbero non essere rilevanti). Uniqid non solo non genera byte crittografici casuali per impostazione predefinita (poiché utilizza l'orologio di sistema), l'entropia aggiunta che si passa viene combinata usando un generatore congruente lineare, che non è crittograficamente sicuro. In effetti, probabilmente significa che si potrebbe supporre che tutte le chiavi API abbiano accesso ad alcune di esse anche se non avevano idea del valore del proprio orologio del server. Infine, mt_rand(), quello che usi come entropia extra, non è neanche un generatore di numeri casuali sicuro.

+23

Il secondo argomento di openssl_random_pseudo_bytes() dovrebbe essere una variabile passata per riferimento. Dopo openssl_random_pseudo_bytes, quella variabile sarà vera o falsa se openssl fosse in grado di utilizzare un algoritmo crittograficamente forte. Non è usato per dire a openssl di usare un algoritmo crittograficamente forte, che proverà a fare comunque. –

8

Se si desidera utilizzare openssl_random_pseudo_bytes è meglio usare l'esecuzione di CrytoLib, questo vi permetterà di generare tutti i caratteri alfanumerici, attaccando BIN2HEX intorno openssl_random_pseudo_bytes sarà solo tradurrà in voi ottenere AF (cappucci) e numeri.

Sostituire path/to/con cui si inserisce il file cryptolib.php (si può trovare su GitHub a: https://github.com/IcyApril/CryptoLib)

<?php 
    require_once('path/to/cryptolib.php'); 
    $token = CryptoLib::randomString(16); 
?> 

La documentazione completa CryptoLib è disponibile all'indirizzo: https://cryptolib.ju.je/. Copre un sacco di altri metodi casuali, crittografia a cascata e generazione di hash e convalida; ma è lì se ne hai bisogno.

Problemi correlati