Tecnicamente, si migliora la sicurezza un po ', ma senza fine utile.
I numeri casuali di solito provengono da un generatore di numeri pseudo-casuali (PRNG) che è esso stesso inseminato con un valore casuale. Lo scopo del PRNG è di allungare il seme originale per produrre un output molto lungo. I numeri casuali vengono solitamente richiamati per due motivi:
-
Per creare dati dall'aspetto casuale per un uso un po 'casuale. Forse per dare ai personaggi di un videogioco una strategia dall'aspetto casuale, magari per eseguire un algoritmo randomizzato , ecc. Il requisito generale è che i valori casuali siano ben distribuiti e superino i test statistici di base, sebbene l'uso esatto imponga esattamente quali sono i requisiti.
-
Per fornire sicurezza crittografica. Forse per generare una chiave segreta, per iniziare la ricerca di un numero primo casuale, ecc. Il requisito è che i valori casuali siano distribuiti molto bene, superino molti test statistici avanzati, abbiano uno spazio seme molto grande e non producano informazioni su altri valori nell'output o qualcosa del seme del PRNG.
I PRNG di solito sono progettati per uno di questi requisiti e non sono uguali. I PRNG per uso occasionale tendono ad essere molto semplici, estremamente veloci e non soddisfano nessuno dei requisiti di un PRNG crittografico. È molto difficile trasformare un semplice PRNG in un PRNG crittografico; per fare ciò ci sarebbe probabilmente molto poco simile al PRNG originale lasciato nello schema PRNG finale sicuro.
Ecco alcuni problemi con la combinazione dei PRNG deboli:
-
Lunghezza del periodo. Quando combini due PRNG in modo lineare (come nell'OP), nel migliore dei casi combinerai le loro lunghezze seme. I PRNG semplici hanno in genere 32 bit o meno di lunghezza seme, che è crittograficamente molto insicuro. In genere dovresti avere almeno 128 bit di spazio seme.
-
Protezione delle sementi. La combinazione delle uscite PRNG non impedirà necessariamente che il seme venga decodificato dall'uscita PRNG. Se un attaccante può ricavare parte del seme, può ridurre drasticamente il carico di lavoro. Derivare il seme dall'output di un PRNG semplice a volte è banale in circostanze appropriate.
-
Bias di output. Combinare linearmente le uscite PRNG non nasconderà necessariamente le loro uscite difettose. Dovrebbe sicuramente migliorare il bias, ma è improbabile che siano validi come un PRNG crittografico. (In pratica, questo è probabilmente meno preoccupante, ma vale comunque la pena di essere menzionato.)
E questo presume che tu semini correttamente il PRNG. È ancora necessario eseguire manualmente la semina come qualsiasi semina predefinita utilizzata dai PRNG semplici è probabilmente basata su qualcosa di qualità molto bassa, come un timestamp.
Il semplice summery è che la combinazione di PRNG deboli offre una sicurezza migliore, ma non il livello di sicurezza che ci si dovrebbe aspettare da un PRNG crittograficamente sicuro. La soluzione è ottenere un PRNG crittografico reale e inizializzarlo con dati casuali da una buona fonte, come /dev/random
o CryptGenRandom()
. Oppure potresti semplicemente utilizzare l'output di quelli direttamente dal momento che sono tecnicamente PRNG stessi seminati da altri dati casuali.
Se openssl_random_pseudo_bytes
imposta il flag che indica che non ha generato byte casuali sicuri, sembrerebbe che ci sia qualcosa di sbagliato nell'ambiente perché i manuali suggeriscono che ci si dovrebbe aspettare che restituisca true
in condizioni normali. Controllare per vedere quale versione di PHP / OpenSSL è installata e se è possibile aggiornarla. Se non riesci a farlo funzionare, considera solo i dati casuali direttamente da /dev/random
o CryptGenRandom()
.