Neden / dev / random'a yazmak / dev / random'dan paralel okumayı daha hızlı yapmıyor?


22

Genelde /dev/random100-500 bayt ve bloktan okuma, entropinin toplanmasını bekler.

Neden /dev/randomdiğer işlemler tarafından bilgi yazmak okumayı hızlandırmaz? Gerekli entropiyi sağlamamalı mı?

gpgÜst üste gizli olmayan anahtarlar vb. Oluşturmak için, yeniden başlatmadan ve her şeye yeniden girmeden, blokaj açma veya benzeri bir yazılım için faydalı olabilir .


3
Sadece /dev/urandombunun yerine okuyun . şifreleme kullanımı için /dev/urandomolduğu kadar güvenlidir/dev/random , davranışı /dev/randomkötü tasarımdır.
Gilles 'SO- kötülük' dur

1
Nasıl geçmek için gpg --gen-keygelen /dev/randomiçin /dev/urandomyeniden başlatmadan?
Vi.

IIRC gpgetti /dev/randomkodlanmış. Uudev yapılandırmanızı , diğer olasılıkların yanı /dev/randomsıra aynı cihazı yapmak için değiştirebilirsiniz /dev/urandom.
Gilles 'SO- kötülük' dur

@Gilles, yine de yeniden başlatılmasını gerektiriyor gpg --gen-key, bu nedenle etkileşimli olarak sorduğu verileri yeniden başlatıyor (veya daha fazla komut satırı parametresi belirtmek gibi daha akıllı yöntemler kullanıyor). Ayrıca kaybedilecek asal sayıyı üreten CPU zamanı (gpg bir dakika çalışabilir, bazı +esleri yazdırabilir ve ardından ek rasgele veri talep edebilir). Ve "bir çekiç alıp ileri zorlayalım" yerine "geri dönelim ve diğer rotaya gidelim" hissini veriyor ...
Vi.

Yanıtlar:


19

Bunun /dev/randomiçin fazladan rastgele bayt sağlama yolunun bir parçası olduğu için yazabilirsiniz /dev/random, ancak yeterli değildir, ayrıca bir ioctl()çağrı yoluyla ek entropi olduğunu da sisteme bildirmeniz gerekir .

Akıllı kart kurulum programımı sınamak için aynı işlevselliğe ihtiyacım vardı , çünkü fare / klavyemin gpgher deneme çalışması için yapılan birkaç çağrı için yeterince üretmesini beklemek istemiyordum . Yaptığım, testlerime paralel olarak izleyen Python programını çalıştırmak. Elbette , rastgele dize hiç rastgele olmadığı için gerçek anahtar üretimi için hiç kullanılmamalıdır gpg(sistem tarafından oluşturulan rasgele bilgi yine de araya girecektir). Dizeyi ayarlamak için harici bir kaynağınız varsa random, o zaman yüksek entropiye sahip olmalısınız. Entropiyi şunlarla kontrol edebilirsiniz:

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)

(Tamamladıktan sonra programı öldürmeyi unutmayın.)


1
Çok daha basit bir çözüm kullanmak olacaktır rngd. Çoğu (tümünde) dağıtımlarda paket olarak bulunur.
Patrick,

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

@Patrick Rastgele eklemek için en az 3 potansiyel çözüm denedim, IIRC rngd onlardan biriydi. Ancak kutudan çıkmazlardı (o zaman Ubuntu 12.04 kurulumu olabilirdi) ve benim için 10 satır kod içeren bu çözüm daha kolaydı.
Anthon,

@Anthon: bir sidenote olarak, mitnik bazı şeyleri saklamak için kullandığından, on yıl önce xs4all.nl gibi görünmemiştim ... :)
woliveirajr

@woliveirajr, hesabımı hacktic.nl hesabımdan 1992 yılında bir yere transfer ettim, 20 yıldan beri Hollanda'da yaşamamış olmama rağmen bir süredir orada bulundum.
Anthon

14

Tipik olarak, çekirdek geliştiricileri tarafından tasarlanır ve belgelenmiştir 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, zaten yazmanın /dev/randomentropi sayısını artırmadığını ve RNDADDENTROPY ioctl'nin (bkz. Rastgele (4) ) entropi için kredi kullanmanın nasıl kullanılabileceğini gösterdi. Açıkçası gerçekten güvenli değil, bu yüzden bir donanım rastgele sayı üreteci mevcut olduğunda bir alternatif.

Aşağıdaki uygulamalar, 512 bayt (4096 bit) rastlantısallık alır /dev/hwrngve onu entropi havuzuna iletir (bayt başına 4 bit entropi kredilendirir, bu benden keyfi bir seçimdir). Bundan sonra , entropi havuzu dolduğunda bloke etmek için select (2) sistem çağrısını çağırır ( rastgele (4) kılavuz sayfasında belgelenmiştir ).

Bir Python sürümü:

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

Arch Linux iso Python yüklü olmadığı için, burada bir Perl versiyonu da var:

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
}

Bu, muhtemelen zaten mevcut olan araçları (Python veya Perl) kullanması dışında , rngd programının ( rng araçlarının bir parçası ) yaptığı (doğrulanmamış) budur.


Donanım rastgele sayı üreticiniz yoksa, güvenli olmayan rasgele değerleri umursamıyorsanız /dev/urandom, yerine kullanabilirsiniz . /dev/hwrng
Lekensteyn

Hmm, hwrng cihazlarının gerektiğinde otomatik olarak entropi oluşturduğunu, ek rngd veya script gerekmediğini keşfettim. getrandom()Sistem çağrısı, 4.8-rc1'den daha büyük olan çekirdeklerde hwrng ile kullanıldığında, bloklama davranışına neden olan bir hata var . Bir geçici çözüm read()iki defadır/dev/random , bkz. Github.com/Lekensteyn/archdir/commit/…
Lekensteyn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.