Dlaczego pisanie do / dev / random nie przyspiesza równoległego czytania z / dev / random?

22

Zazwyczaj czytanie z /dev/randomprodukuje 100-500 bajtów i bloków, czekając na pobranie entropii.

Dlaczego zapisywanie informacji /dev/randomprzez inne procesy nie przyspiesza czytania? Czy nie powinien zapewnić wymaganej entropii?

Może być przydatny do odblokowywania gpglub podobnego oprogramowania bez ponownego uruchamiania go i ponownego wprowadzania wszystkiego, do generowania kluczy, które nie są ściśle tajne itp.

Vi.
źródło
3
Po prostu czytaj /dev/urandomzamiast. /dev/urandomjest tak samo bezpieczny, jak w /dev/randomprzypadku zastosowania kryptograficznego , zachowanie /dev/randomjest złym projektem.
Gilles 'SO - przestań być zły'
1
Jak zmienić gpg --gen-keyz /dev/randomna /dev/urandombez ponownego uruchamiania?
Vi.
IIRC gpgma /dev/randomzakodowane na stałe. Możesz zmienić konfigurację udev, aby stworzyć /dev/randomto samo urządzenie, co /dev/urandommiędzy innymi.
Gilles 'SO - przestań być zły'
@Gilles, wciąż wymaga ponownego uruchomienia gpg --gen-key, dlatego też ponownie wymaga danych, o które pyta interaktywnie (lub przy użyciu bardziej sprytnych metod, takich jak określenie większej liczby parametrów wiersza poleceń). Również czas procesora generujący liczbę pierwszą mógłby zostać utracony (gpg może działać przez minutę, wydrukować niektóre +es, a następnie zażądać dodatkowych losowych danych). I daje uczucie „wracajmy i idź inną drogą” zamiast „weźmy młotek i zmuśmy go do przodu” ...
Vi.

Odpowiedzi:

19

Możesz pisać do, /dev/randomponieważ jest to część sposobu na dostarczenie dodatkowych losowych bajtów /dev/random, ale to nie wystarczy, musisz również powiadomić system, że istnieje dodatkowa entropia za pośrednictwem ioctl()połączenia.

Potrzebowałem tej samej funkcjonalności do testowania mojego programu instalacyjnego karty inteligentnej , ponieważ nie chciałem czekać, aż moja mysz / klawiatura wygeneruje wystarczającą liczbę połączeń, gpgktóre zostały wykonane dla każdego uruchomienia testowego. To, co zrobiłem, to uruchomienie programu Python, który następuje równolegle z moimi testami. Oczywiście nie należy go w ogóle używać do gpggenerowania prawdziwych kluczy, ponieważ losowy ciąg nie jest wcale losowy (losowe informacje generowane przez system nadal będą przeplatane). Jeśli masz źródło zewnętrzne, dla którego chcesz ustawić ciąg random, powinieneś mieć wysoką entropię. Możesz sprawdzić entropię za pomocą:

cat /proc/sys/kernel/random/entropy_avail

Program:

#!/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)

(Nie zapomnij zabić programu po zakończeniu.)

Anthon
źródło
1
O wiele prostsze rozwiązanie byłoby użyć rngd. Jest dostępny jako pakiet w większości (wszystkich?) Dystrybucji.
Patrick
4
random = "3420348024823049823-984230942049832423l4j2l42j"patrz xkcd.com/221
user253751
@ Patric Wypróbowałem co najmniej 3 potencjalne rozwiązania dla dodawania losowości, IIRC rngd był jednym z nich. Ale nie działałyby od razu po wyjęciu z pudełka (może to być wtedy instalacja Ubuntu 12.04), a dla mnie to rozwiązanie, z 10 liniami kodu, było prostsze.
Anthon
@Anthon: jako sidenote, nie wydaje mi się xs4all.nl, ponieważ mitnik używał go do przechowywania niektórych rzeczy, dekady temu ... :)
woliveirajr
@woliveirajr, miałem swoje konto z hacktic.nl przeniesione tam gdzieś w 1992 roku, byłem tam jakiś czas, chociaż nie mieszkam w Holandii od ponad 20 lat.
Anthon
14

Zazwyczaj jest zaprojektowany przez programistów jądra i udokumentowany w 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.
Cuonglm
źródło
1

Anthony wyjaśnił już, że pisanie do /dev/randomnie zwiększa liczby entropii i pokazał, w jaki sposób można użyć ioctl RNDADDENTROPY (patrz random (4) ) do uznania entropii. To oczywiście nie jest naprawdę bezpieczne, więc tutaj jest alternatywa, gdy dostępny jest sprzętowy generator liczb losowych.

Następujące implementacje pobierają losowo 512 bajtów (4096 bitów) /dev/hwrngi przesyłają je do puli entropii (przypisując 4 bity entropii na bajt, to ode mnie arbitralny wybór). Następnie wywoła syscall select (2), aby zablokować, gdy pula entropii jest pełna (udokumentowana na losowej (4) stronie podręcznika).

Wersja 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], [])

Ponieważ w Arch Linux iso nie zainstalowano Pythona, tutaj jest również wersja Perla:

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
}

Prawdopodobnie właśnie to robi program rngd (część rng-tools ) (niezweryfikowany), z tym wyjątkiem, że używa narzędzi (Python lub Perl), które są już powszechnie dostępne.

Lekensteyn
źródło
Jeśli nie masz sprzętowego generatora liczb losowych, możesz użyć /dev/urandomzamiast tego, /dev/hwrngjeśli absolutnie nie zależy ci na niepewnych losowych wartościach .
Lekensteyn,
Hmm, odkryłem, że urządzenia hwrng automatycznie generują entropię w razie potrzeby, nie są potrzebne żadne dodatkowe rngd ani skrypt. Występuje błąd, gdy getrandom()syscall jest używany z hwrng na jądrach starszych niż 4.8-rc1, co powoduje blokowanie. Obejściem jest read()dwa razy więcej /dev/random, patrz github.com/Lekensteyn/archdir/commit/…
Lekensteyn,