La semplice risposta è che se non ti fidi di CryptGenRandom()
allora sei condannato. Infatti, CryptGenRandom()
è fornito dal sistema operativo, e se il sistema operativo è ostile allora c'è ben poco da fare per difendersi da esso. Un sistema operativo ostile può ispezionare tutta la tua RAM, registrare tutte le tue password, inviare tutti i tuoi dati a terze parti esterne.
La risposta meno semplice si basa su una sottigliezza, che è che potresti sfidare CryptGenRandom()
mentre non supposi realmente che il sistema operativo sia ostile. Forse consideri che CryptGenRandom()
è semplicemente imperfetto, per caso e non per malizia, e offre casualità di scarsa qualità, mentre nessun altro componente del sistema operativo tenta attivamente di tradirti.
In tal caso, diventa sensato aumentare CryptGenRandom()
con qualche extra entropia. L'entropia proviene da eventi fisici e il sistema operativo è ideale per raccogliere eventi fisici; le applicazioni sono in una posizione molto meno ideale per questo. Tuttavia, alcune persone hanno provato. Ad esempio, esiste un raccoglitore entropico applicativo in GnuPG (almeno nella versione 1.4.14, cercare il file rndw32.c
).
Il modo corretto per raccogliere entropia è prendere tutti gli "eventi" (ad esempio "la chiave X è stata premuta al tempo T"), concatenarli insieme, quindi hash l'intero lotto con una funzione di hash corretta come SHA-256. Quindi utilizza l'output come seme per un PRNG protetto da crittografia . In particolare, non eliminare completamente CryptGenRandom()
; chiamalo per ottenere alcuni byte di output (ad esempio, 16 byte) e aggiungi quell'output come un "evento" come tutti gli altri che raccogli. La bellezza dell'hashing è che anche se l'evento è difettoso in modo malevolo, non può ridurre l'entropia risultante; può solo contribuire positivamente (nel peggiore dei casi, non contribuisce a quantità significative di entropia).
La parte difficile della generazione casuale non sta ottenendo l'entropia; sta stimando quanto hai ottenuto. Un evento hardware è "entropia utile" esattamente nella misura in cui qualsiasi potenziale aggressore non può prevederne il contenuto. Ad esempio, un utente malintenzionato che osserva la rete può prevedere il momento esatto in cui la macchina riceve un pacchetto in entrata, con precisione fino, forse, al microsecondo. Se credi che quell'evento con precisione in nanosecondi ( Contatori di timestamp siano convenienti per questo - Windows li chiama "contatori delle prestazioni") , quindi si può considerare che ogni pacchetto in ingresso produce 10 bit di entropia (poiché 2 10 è approssimativamente uguale a 1000, che è il rapporto tra microsecondi e nanosecondi). È tutto relativo a un contesto fisico specifico; fare un RNG unico nel suo genere in un software puro implica necessariamente un sacco di esagerazione.