2012-12-30 15 views
9

Sto sviluppando un sito in php 5.4 e mi stavo chiedendo quale è meglio usare per generare un salt casuale per la sicurezza della password?dovrei usare urandom o openssl_random_pseudo_bytes?

$salt = sha1(openssl_random_pseudo_bytes(23)); 

o

$seed = ''; 
$a = @fopen('/dev/urandom','rb'); 
$seed .= @fread($a,23); 
$salt = sha1(seed); 

o devo solo andare con:

$salt = openssl_random_pseudo_bytes(40); 

o

$salt = ''; 
$a = @fopen('/dev/urandom','rb'); 
$salt .= @fread($a,23); 
+4

L'uso di 'sha1()' ridurrà notevolmente l'efficacia del sale casuale poiché lo convertirà in una stringa di 40 caratteri e contenente solo caratteri 0-9 e a-f. Ci sarebbero molte meno combinazioni (cioè meno casuali) che se usassi solo 40 byte da 'openssl_random_pseudo_bytes()' –

+0

io vado con entrambi i tuoi suggerimenti – John

risposta

10

Per motivi di sicurezza si sta meglio utilizzando openssl_random_pseudo_bytes. OpenSSL si occupa di raccogliere abbastanza entropia per servirti una buona casualità. /dev/urandom è concepito per mai blocco e potrebbe essere indotto a dare byte non così casuali.

Con byte casuali non è necessario eseguirli tramite SHA1.

Per riassumere il tutto, do:

$salt = openssl_random_pseudo_bytes(40, $cstrong); 
if (! $cstrong) { 
    exit('This should not happen'); 
} 
+1

In realtà, 'openssl_rand_pseudo_bytes' non è _guarantee_ true randomness, più che '/ dev/urandom' fa; questo è ciò che significa "pseudo" nel nome. In pratica, tuttavia, entrambi producono un output indistinguibile dal casuale con qualsiasi mezzo noto. –

+0

@IlmariKaronen Ovviamente non si ottiene la casualità vera. Ho scritto solo "buono"; ciò che OpenSSL chiama "crittograficamente forte". Questo è il motivo per cui ho fatto il test per verificare che il risultato sia crittograficamente forte. – kmkaplan

+1

[Non utilizzare OpenSSL] (https://github.com/ramsey/uuid/issues/80). –

9

In pratica, non v'è quasi certamente nessuna differenza.

Entrambi openssl_random_pseudo_bytes e /dev/urandom forniscono una fonte crittograficamente sicura di byte pseudocasuali. Né è garantito che sia veramente casuale, ma in pratica, entrambi dovrebbero essere indistinguibili dalla vera casualità con qualsiasi tecnica nota o prevedibile.

Kmkaplan è tecnicamente corretta nel notare che /dev/urandom potrebbe ritornare uscita teoricamente prevedibile in determinate condizioni, come osservato in man unrandom:

"Una lettura dal/urandom dispositivo /dev non bloccherà in attesa di più entropia: di conseguenza, se non vi è un'entropia sufficiente nel pool di entropia, i valori restituiti sono teoricamente vulnerabili a un attacco crittografico sugli algoritmi utilizzati dal driver. La conoscenza di come eseguire questa operazione non è disponibile nell'attuale letteratura non classificata, ma è teoricamente possibile che un tale attacco possa esistere Se questa è una preoccupazione nella tua applicazione n, utilizzare invece /dev/random. "

Tuttavia, lo stesso è in realtà vale openssl_random_pseudo_bytes (che calls la funzione OpenSSL RAND_pseudo_bytes internamente), come osservato nella OpenSSL documentation:

"RAND_pseudo_bytes() mette num byte pseudo-casuale in BUF. Le sequenze di byte pseudo casuali generate da RAND_pseudo_bytes() saranno univoche se hanno una lunghezza sufficiente, ma non sono necessariamente imprevedibili. Possono essere utilizzate per scopi non crittografici e per determinati scopi protocolli ptografici, ma solitamente non per la generazione di chiavi, ecc."

Nessuno di questi avvertimenti dovrebbero in realtà ti spaventare di utilizzare questi metodi — le debolezze che descrivono sono solo teoriche, tranne forse in determinate circostanze artificiose (ad esempio su un dispositivo embedded senza disco, senza RNG hardware immediatamente dopo boot up), e non dovrebbe essere di interesse pratico in situazioni in cui normalmente viene implementato PHP

Il risultato è che nessuno dei due metodi di generazione di numeri casuali sarà the weakest link nel proprio sistema di crittografia, quindi è possibile scegliere in modo sicuro uno dei due. Se ti senti paranoico, potresti persino usare entrambi.


Ps. Uno dei vantaggi di openssl_random_pseudo_bytes è che funziona anche su Windows. D'altra parte, /dev/urandom è disponibile su Unix anche se l'estensione OpenSSL PHP non è installata. Pertanto, per garantire la massima portabilità, è necessario implementare il supporto per entrambi.

Inoltre, verificare sempre di aver ricevuto il numero di byte previsto; ad esempio, il codice basato su /dev/urandom nella domanda precedente potrebbe restituire automaticamente una stringa vuota su sistemi come Windows in cui non esiste /dev/urandom.

+0

'RAND_pseudo_bytes' e' openssl_random_pseudo_bytes' restituisce un codice che dice "se i byte generati sono crittograficamente forti". – kmkaplan