/ dev / randomに書き込むと、/ dev / randomからの並列読み取りが速くならないのはなぜですか?


22

通常、読み取り/dev/randomは100〜500バイトとブロックを生成し、エントロピーが収集されるのを待ちます。

/dev/random他のプロセスによる情報の書き込みが読み取りを高速化しないのはなぜですか?必要なエントロピーを提供すべきではありませんか?

gpg再起動せずにすべてを再入力せずにブロック解除または同様のソフトウェアを使用する場合、非スーパートップシークレットキーを生成する場合などに役立ちます。


3
/dev/urandom代わりに読んでください。暗号化の使用/dev/urandomと同じくらい安全ですが/dev/random、の動作/dev/randomは設計が悪いです。
ジル 'SO-悪であるのをやめる' 14

1
どのように切り替えてgpg --gen-keyから/dev/random/dev/urandom再起動せず?
Vi。

IIRC gpg/dev/randomハードコーディングされています。udev構成を変更して、他の可能性の中でも特に/dev/randomと同じデバイスを作成できます/dev/urandom
ジル 'SO-悪であるのをやめる' 14

@Gilles、まだ再起動が必要gpg --gen-keyです。したがって、対話的に要求するデータを再レンダリングします(または、より多くのコマンドラインパラメーターを指定するなど、より賢い方法を使用します)。また、プライムホールドを生成するCPU時間も失われます(gpgは1分間動作し、+esを出力してから追加のランダムデータを要求できます)。そして、「ハンマーを取って前方に押し出そう」の代わりに、「戻って他のルートに行こう」という感覚を与えます...
Vi。

回答:


19

/dev/random追加のランダムバイトを提供する方法の一部であるため書き込むことができますが/dev/random、それだけでは不十分ですioctl()。また、呼び出しによって追加のエントロピーがあることをシステムに通知する必要があります。

マウス/キーボードがテストの実行ごとに行われるいくつかの呼び出しに十分に生成されるのを待ちたくないので、スマートカードセットアッププログラムのテストにも同じ機能が必要でしたgpg。私がしたことは、Pythonプログラムを実行することで、これはテストと並行して実行されます。もちろん、ランダム文字列はまったくランダムではないため、実際のキー生成にはまったく使用しないでくださいgpg(システムで生成されたランダム情報はインターリーブされます)。に文字列を設定する外部ソースがある場合random、高いエントロピーを実現できるはずです。エントロピーを確認するには:

cat /proc/sys/kernel/random/entropy_avail

プログラム:

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

(完了後にプログラムを強制終了することを忘れないでください。)


1
より簡単な解決策は、を使用することrngdです。ほとんどの(すべて?)ディストリビューションでパッケージとして利用可能です。
パトリック14

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

@Patrickランダム性を追加するために少なくとも3つの潜在的なソリューションを試しましたが、IIRC rngdはその1つでした。しかし、それらはそのままでは機能せず(当時のUbuntu 12.04セットアップの場合もあります)、私にとってこのソリューションは10行のコードで簡単でした。
アントン14

@Anthonは:mitnikは、数十年前にいくつかのものを保存するためにそれを使用するので追記として、私は:) ... xs4all.nl思えなかった
woliveirajr

@woliveirajr、私はhacktic.nlからのアカウントを1992年のどこかに転送しました。私は20年以上オランダに住んでいませんが、しばらくそこにいます。
アントン14

14

通常、それはカーネル開発者によって設計され、文書化されています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は、書き込み/dev/randomはエントロピーカウントを増加させないことを既に説明し、エントロピーのクレジットにRNDADDENTROPY ioctl(random(4)を参照)を使用する方法を示しました。それは明らかに本当に安全ではないので、ハードウェア乱数ジェネレータが利用可能な場合の代替手段があります。

次の実装は/dev/hwrng、エントロピープールから512バイト(4096ビット)のランダム性を取得し、エントロピープールに転送します(バイトごとに4ビットのエントロピーをクレジットします。これは私からの任意の選択です)。その後、エントロピープールが一杯になるとブロックするselect(2) syscallを呼び出します(random(4)マンページに記載されています)。

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

Arch Linux isoにはPythonがインストールされていなかったため、ここには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
}

これはおそらくrngdプログラム(rng-toolsの一部)が行うこと(未検証)です。ただし、既に一般的に利用可能なツール(PythonまたはPerl)を使用する点が異なります。


ハードウェア乱数ジェネレーターがない場合は、安全でない乱数値をまったく気にしない場合の/dev/urandom代わりに使用できます/dev/hwrng
Lekensteyn

うーん、必要なときにhwrngデバイスが自動的にエントロピーを生成し、追加のrngdやスクリプトは必要ないことを発見しました。ただしgetrandom()、4.8-rc1よりも古いカーネルでhwrngでsyscallを使用すると、ブロック動作が発生するバグがあります。回避策はからread()2回です。github.com/dev/random
Lekensteyn /
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.