Perché scrivere su / dev / random non rende più veloce la lettura parallela da / dev / random?


22

In genere la lettura da /dev/randomproduce 100-500 byte e blocchi, in attesa che venga raccolta un'entropia.

Perché la scrittura di informazioni /dev/randomda parte di altri processi non accelera la lettura? Non dovrebbe fornire l'entropia richiesta?

Può essere utile per sbloccare gpgo software simile senza riavviarlo e reinserire tutto, per generare chiavi non super-top-secret, ecc.


3
Basta leggere /dev/urandominvece da . /dev/urandomè sicuro come /dev/randomper l'uso crittografico , il comportamento di /dev/randomè una cattiva progettazione.
Gilles 'SO- smetti di essere malvagio' il

1
Come passare gpg --gen-keyda /dev/randoma /dev/urandomsenza riavviare?
Vi.

IIRC gpgha /dev/randomun codice hard. È possibile modificare la configurazione di udev per creare /dev/randomlo stesso dispositivo /dev/urandom, tra le altre possibilità.
Gilles 'SO- smetti di essere malvagio' il

@Gilles, richiede ancora il riavvio gpg --gen-key, quindi reintegrare i dati che richiede in modo interattivo (o utilizzando metodi più intelligenti come specificare più parametri della riga di comando). Anche il tempo di CPU che genera il numero primo andrebbe perso (gpg può funzionare un minuto, stampare alcuni +es e quindi richiedere ulteriori dati casuali). E dà la sensazione "torniamo indietro e prendiamo l'altra strada" invece di "prendiamo un martello e costringiamolo in avanti" ...
Vi.

Risposte:


19

Puoi scrivere /dev/randomperché fa parte del modo di fornire byte casuali extra a /dev/random, ma non è sufficiente, devi anche avvisare il sistema che c'è un'entropia aggiuntiva tramite una ioctl()chiamata.

Avevo bisogno della stessa funzionalità per testare il mio programma di installazione della smart card , poiché non volevo aspettare che il mio mouse / tastiera generasse abbastanza per le diverse chiamate gpgeffettuate per ogni esecuzione del test. Quello che ho fatto è stato eseguire il programma Python, che segue, parallelamente ai miei test. Ovviamente non dovrebbe essere usato per la vera gpggenerazione di chiavi, poiché la stringa casuale non è affatto casuale (le informazioni casuali generate dal sistema saranno comunque interfogliate). Se hai una fonte esterna per cui impostare la stringa random, allora dovresti essere in grado di avere un'entropia elevata. Puoi verificare l'entropia con:

cat /proc/sys/kernel/random/entropy_avail

Il programma:

#!/usr/bin/env python
# For testing purposes only 
# DO NOT USE THIS, THIS DOES NOT PROVIDE ENTROPY TO /dev/random, JUST BYTES

import fcntl
import time
import struct

RNDADDENTROPY=0x40085203

while True:
    random = "3420348024823049823-984230942049832423l4j2l42j"
    t = struct.pack("ii32s", 8, 32, random)
    with open("/dev/random", mode='wb') as fp:
        # as fp has a method fileno(), you can pass it to ioctl
        res = fcntl.ioctl(fp, RNDADDENTROPY, t)
    time.sleep(0.001)

(Non dimenticare di uccidere il programma dopo aver finito.)


1
Una soluzione molto più semplice sarebbe usare rngd. È disponibile come pacchetto nella maggior parte delle (tutte?) Distro.
Patrick,

4
random = "3420348024823049823-984230942049832423l4j2l42j"vedi xkcd.com/221
user253751

@Patrick Ho provato almeno 3 potenziali soluzioni per aggiungere casualità, IIRC rngd era una di queste. Ma non funzionerebbero immediatamente (potrebbe essere la configurazione di Ubuntu 12.04 al momento), e per me questa soluzione, con 10 righe di codice, è stata più semplice.
Anthon,

@Anthon: come sidenote, non mi sembra xs4all.nl da quando mitnik l'ha usato per conservare alcune cose, decenni fa ... :)
woliveirajr

@woliveirajr, ho avuto il mio account da hacktic.nl trasferito lì da qualche parte nel 1992, ci sono stato un po ', anche se non vivo nei Paesi Bassi da oltre 20 anni.
Anthon,

14

Tipicamente, è progettato dagli sviluppatori del kernel e documentato in man 4 random:

Writing to /dev/random or /dev/urandom will update the entropy pool
with the data written, but this will not result in a higher entropy
count.  This means that it will impact the contents read from both
files, but it will not make reads from /dev/random faster.

1

Anthony ha già spiegato che scrivere su /dev/randomnon aumenta il conteggio di entropia e ha mostrato come si può usare lo ioctl RNDADDENTROPY (vedi random (4) ) per accreditare l'entropia. Ovviamente non è davvero sicuro, quindi ecco un'alternativa quando è disponibile un generatore di numeri casuali hardware.

Le seguenti implementazioni prendono 512 byte (4096 bit) di casualità da /dev/hwrnge inoltrano al pool di entropia (accreditando 4 bit di entropia per byte, questa è una mia scelta arbitraria). Dopodiché invocherà il syscall select (2) per bloccare quando il pool di entropia è pieno (documentato nella manpage random (4) ).

Una versione di Python:

import fcntl, select, struct
with open('/dev/hwrng', 'rb') as hw, open('/dev/random') as rnd:
    while True:
        d = hw.read(512)
        fcntl.ioctl(rnd, 0x40085203, struct.pack('ii', 4 * len(d), len(d)) + d)
        select.select([], [rnd], [])

Dal momento che iso Arch Linux non aveva installato Python, ecco anche una versione Perl:

open my $hw, "</dev/hwrng" and open my $rnd, "</dev/random" or die;
for (;;) {
    my $l = read $hw, my $d, 512;
    ioctl $rnd, 0x40085203, pack("ii", 4 * $l, $l) . $d or die;
    vec(my $w, fileno $rnd, 1) = 1;
    select undef, $w, undef, undef
}

Questo è probabilmente ciò che fa il programma rngd (parte di rng-tools ) (non verificato), tranne per il fatto che utilizza strumenti (Python o Perl) che sono già comunemente disponibili.


Se non si dispone di un generatore di numeri casuali hardware, è possibile utilizzare /dev/urandominvece di /dev/hwrngnon preoccuparsi assolutamente di valori casuali non sicuri .
Lekensteyn,

Hmm, ho scoperto che i dispositivi hwrng generano automaticamente entropia quando necessario, non sono necessari rngd o script aggiuntivi. C'è un bug però quando getrandom()si usa syscall con hwrng su kernel più vecchi di 4.8-rc1 che si traducono in un comportamento di blocco. Una soluzione alternativa è di read()due volte /dev/random, consultare github.com/Lekensteyn/archdir/commit/…
Lekensteyn
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.