/dev/randomは、デバイスドライバその他の情報源から集めた環境ノイズを利用して、真の乱数性を得るのが目的である。
参考:/dev/random
エントロピープールが空の場合、/dev/random から読み出そうとするとブロックされ、環境ノイズの収集がなされるまで待たされる。
最近のCPUでは乱数生成がはやい話
Ivy Bridge以降のCPUではCPU内に乱数生成器が含まれています。それに対応した最近のrngdをつかうとそれなりに乱数生成が速くてしあわせになれます。
linuxでは乱数を取得するために /dev/random と /dev/urandom の2種類のデバイスがあります。
それぞれの説明は man 4 random にみっちり書いてありますが、かいつまんで言うと:
・random: カーネルがあつめてきたノイズを元に品質の高い疑似乱数を生成します。ノイズが不足するとblockします。
・urandom: カーネルがあつめてきたノイズを元にそこそこの品質の疑似乱数を生成します。品質はそこそこですがblockしないので速いです。
ためしにcat /dev/random とかすると1kとか4kくらい乱数が出力されて止まってしまう。
これでは割と足りないので選択肢が2種類。
1) 品質をあきらめてurandomを使う、
2) 乱数生成器をつけてrngd経由で書き込みとエントロピーの追加をおこなう。乱数生成器は一部のチップセットに内蔵されたりしてたんですが、 専用ハードウェアもあったりします。
そこでIvy Bridge世代ではrdrand命令を追加して、CPUのチップ内で乱数生成をして専用命令で読みだせるようにしました。
実際つかってみましょう。rngdの最近のバージョンでは、rdrand命令に対応しています
投稿時刻 15th December 2013、投稿者 Moriwaka Kazuo さん
# cat /proc/sys/kernel/random/poolsize 4096
# cat /proc/sys/kernel/random/entropy_avail
# strace -tt -s 1024 -f -o /tmp/tmp1.txt -e trace=stat ./TEST
/dev/urandom へのアクセスはブロックされることがないが、/dev/random に比べると、真の乱数ではなく擬似乱数的に生成されている。
JDK では、-Djava.security.egd=file:/dev/../dev/urandom プロパティとして 提供されており、Java コマンドラインの場合には、以下のように実行します。 例) java -Djava.security.egd=file:/dev/../dev/urandom <クラス名> または、お使いの JDK に含まれる $JDK_HOME/jre/lib/security/java.security の securerandom.source パラメータを以下のように変更することでも回避可能です。 securerandom.source=file:/dev/./urandom
/dev/urandomを使うように設定したrngdデーモンの起動させ、エントロピーを増やす
/usr/lib/systemd/system/rngd.service
以下のように編集します。
ExecStart=/sbin/rngd -f -r /dev/urandom
編集の反映
# systemctl daemon-reload
# systemctl start rngd # systemctl status rngd
# yum install rng-tools
/etc/default/rng-tools
HRNGDEVICE=/dev/urandom
もしくは
/etc/init.d/rngd
#HRNGDEVICE=/dev/hwrng HRNGDEVICE="/dev/urandom -t 10 -i"
# service rngd start