No, scusa, il tuo generatore è terribilmente cattivo. Lo semini con valori che non hanno molta entropia (il PID si adatta a 16 bit ...) o sono altamente ipotizzabili (il "tempo corrente" non è esattamente un valore segreto, chiunque può conoscerlo con notevole precisione). E il generatore che si nasconde sotto rand()
è noto per essere irrinunciabile (dipende dal sistema operativo attuale, ma molti sistemi usano un generatore di congruenza lineare che può essere facilmente invertito).
Otterrai qualcosa che sembra vagamente casuale a prima vista, ma non resisterà ai tentativi riusciti di scoppiarlo, cioè a prevedere l'uscita futura del generatore. Resistere ai tentativi di cracking da parte di aggressori intelligenti è tutto ciò che riguarda la sicurezza. Il tuo generatore potrebbe essere appropriato per alcuni usi non correlati alla sicurezza, sebbene (anche se rand()
è noto per essere piuttosto negativo in quelli).
Per la generazione corretta del numero casuale, è necessario:
- un seme iniziale con sufficiente entropia;
- a PRNG crittograficamente sicuro che espanderà quel seme in un lungo flusso di byte che sarà indistinguibile dalla casualità (anche agli occhi di un individuo intelligente e potente con grandi computer intenzionati a predire il prossimo byte casuale.
Il seme iniziale deve provenire da alcuni eventi hardware (casualità "fisica"), perché il software è, fino al livello transistor, deterministico. Il sistema operativo è in una posizione ideale per raccogliere eventi fisici (è il suo lavoro, dopo tutto). Pertanto, utilizzare il sistema operativo. Questo significa:
- Su sistemi di tipo Unix (come Linux, FreeBSD, Solaris, MacOS X ...), usa
/dev/urandom
( non /dev/random
; vedi questa risposta per i dettagli).
- In Windows (Win32), chiama
CryptGenRandom()
.
- Su Java, usa
java.security.SecureRandom
.
- Su .NET, usa
System.Security.Cryptography.RNGCryptoServiceProvider
.