Sementi casuali affidabili per RNG

4

Voglio creare le password del mio computer con un RNG, ma sto pensando a una cosa: userei Python per scrivere quello script e l'RNG è controllato da un seme, molto probabilmente il tempo. Se dovessi generare le mie password con un RNG che è stato seminato con il tempo e qualcuno lo sa, potrebbe provare a forzare le password generate usando il tempo in cui ho creato le password.

Per dirla in breve, secondo me il tempo non è un buon seme per un RNG se l'output dovrebbe rimanere segreto, ma quali sono i buoni semi per un RNG? Ho già sentito parlare di idee come leggere la memoria allocata (se è stata appena allocata, dovrebbe contenere byte casuali), usare il PID corrente o usare gli ultimi bit della posizione del cursore del mouse. Quale di queste idee (o altre idee) è veramente casuale?

    
posta Sirac 29.05.2014 - 00:44
fonte

2 risposte

3

Dipende dalla piattaforma.

In generale, dovresti considerare l'utilizzo dei binding OpenSSL per utilizzare l'API RAND_ * di OpenSSL. Assicurati di inizializzarlo correttamente. La mancata lettura della documentazione di OpenSSL renderà un compromesso di sicurezza su praticamente tutti i sistemi operativi a causa di seed RNG impropri. Anche i "grandi" sono stati morsi da questo.

Sui sistemi operativi Unix-like incluso BSD, Hurd e Mac OS X, dovresti leggere da /dev/arandom (se esiste), o /dev/urandom (se esiste), o /dev/random ( solo se nessuno degli altri due esiste). Se nessuno di questi ① esiste e ② sono dispositivi di carattere, interrompi con un errore per evitare compromessi. Davvero non vuoi "inventare" uno schema RNG / seeding!

Sui sistemi Windows® ... per prima cosa prendi in considerazione se vuoi davvero farlo. Questo è già un potenziale compromesso per la sicurezza. Quindi, leggi da /dev/urandom se esiste (Cygwin) oppure usa CryptGenRandom API. Non sono sicuro che ci siano binding Python per questo, ma non è difficile da fare in C, e può essere trasformato in un modulo Python compilato. Forse con FFI ...

Quando si utilizza OpenSSL, si consideri di impostare RANDFILE per mantenere un seed tra le chiamate di programmi, specialmente su Windows®. Considerare la preconfigurazione di questa da una buona entropia nota. Magari mixando roba da random.org , randomnumbers.info o fourmilab.ch del servizio Hotbits (ma, ancora una volta, non solo prendere da lì, poiché è trasmesso attraverso la rete). Tieni presente che RANDFILE non viene gestito correttamente da OpenSSL per impostazione predefinita: invece di read + RAND_add + write + close all'avvio del programma, normalmente viene letto all'avvio del programma e scritto solo alla fine del programma; questo è meglio ma solo se il tuo programma (e tutti gli altri programmi che lo utilizzano) non sta eseguendo più di un'istanza in un dato momento.

Non utilizzare nessuno di questi:

  • ID processo
  • Ora
  • Posizione del mouse
  • Contenuto dello schermo
  • Contenuto della memoria "non inizializzata" - spesso non è non inizializzata (anche malloc() risultati, che la libreria C potrebbe non inizializzarsi, è inizializzato dal sistema operativo per la sola ragione per cancellare ciò che era lì prima (ad esempio da un altro processo), e il modo più semplice per azzerarlo è azzerarlo), e se è, questo è normalmente un comportamento indefinito, che può portare a tutti i tipi di caos

È vero che queste sono (alcune delle) fonti di input utilizzate dal sistema operativo e / o OpenSSL per le loro implementazioni RNG. Ma queste persone sanno (più o meno, ma un po 'più di te) cosa stanno facendo e, cosa molto più importante, non sono le sole fonti. Non sono tutti segreti e un aggressore può sperimentarli. Ancora più importante, la loro gamma di valori non è eccezionale. Inoltre, non scrivere da soli alcun codice "input da tastiera" (valori e tempistiche). Il SO gestisce normalmente la conversione keypress-to-entropy. Chiedete al sistema operativo una buona entropia e l'errore se non ce n'è.

Non utilizzare il generatore di numeri casuali dell'hardware del sistema come unica fonte! Possono essere compromessi. Inoltre, potrebbe non esistere nemmeno o l'accesso è vietato (si pensi alle macchine virtuali).

Il missaggio di uno di questi in un pool è buono, ma poi di nuovo il sistema operativo eseguirà un molto lavoro migliore rispetto all'applicazione nello spazio utente.

    
risposta data 30.05.2014 - 17:49
fonte
2

Python fornisce la funzione os.urandom() per leggere i byte dal sistema operativo CSPRNG menzionato di Stephen Touset sopra.

Per l'API di modulo random più attraente, fornisce anche la classe random.SystemRandom() che utilizza la stessa fonte.

Non c'è motivo di fare qualcosa di più complicato.

I already heard of ideas like reading allocated memory (if it was just allocated, it should contain random bytes) ...

A proposito, questo ha portato a uno dei altri famigerati disastri di sicurezza nella memoria recente . (Bene, prima del 2013, comunque.) CSPRNG di OpenSSL utilizzava la memoria non inizializzata come una fonte extra discutibile di "entropia" - non la sorgente solo , naturalmente, ma mescolarla non poteva far male, giusto ? Nel 2006, uno sviluppatore Debian si è ammalato degli avvertimenti di Valgrind che ha prodotto e disabilitato quella riga di codice. Interpretando erroneamente il codice non intuitivo di OpenSSL, hanno anche disabilitato inavvertitamente ogni altra fonte di entropia tranne il PID , quindi per due anni gli utenti di Debian, Ubuntu e la società stavano ottenendo solo 32.767 diversi " "stream" casuali.

    
risposta data 31.05.2014 - 01:05
fonte

Leggi altre domande sui tag