/ dev / randomから読み取ってもデータは生成されません


19

私はよくコマンドを使用します

cat /dev/urandom | strings --bytes 1 | tr -d '\n\t ' | head --bytes 32

擬似ランダムパスワードを生成します。これはでは機能しません/dev/random

具体的には

  • cat /dev/urandom | strings --bytes 1 | tr -d '\n\t ' 出力を生成します
  • cat /dev/random | strings --bytes 1 出力を生成します
  • cat /dev/random | strings --bytes 1 | tr -d '\n\t ' 出力を生成しません

注意:使用/dev/randomする場合、エントロピーを生成するために、マウスを小刻みに動かしたり、キー(Ctrlキー、Shiftキーなど)を押したりする必要があります。

最後の例が機能しないのはなぜですか?ないtrことを大きな内部バッファのいくつかの種類を持って/dev/urandomすぐに塗りつぶししかしが/dev/randomないのですか?

PS CentOS 6.5を使用しています

cat /proc/version
Linux version 2.6.32-431.3.1.el6.x86_64 (mockbuild@c6b10.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Jan 3 21:39:27 UTC 2014

ディストリビューション、カーネルバージョンは何ですか?Cygwinでは両方の値を返します。
Kiwy 14

@Kiwy編集を参照してください。
アーロンJラング14

1
pwgen特に知っていpwgen -sますか?
MvG 14

2
-sスイッチは、彼らが、あまり記憶に残るより真にランダムになります。@Boyd:makepasswdはDebianベースのディストリビューション以外にも広く利用可能ですか?私の考えではpwgenはCentOSで使用できますがmakepasswdは使用できません
MvG 14

1
しょーた makepasswd私のプラットフォームでは利用できない@ MvGに同意します。とにかくありがとう
アーロンJラング14

回答:


27

最終的にはそうなります。

に:

cat /dev/random | strings --bytes 1 | tr -d '\n\t '

cat バッファリングすることはありませんが、ここで連結するものは何もないので、とにかく余分です。

< /dev/random strings --bytes 1 | tr -d '\n\t '

stringsただし、その出力はもはやないので、出力は端末に行くときのとは対照的に、(4または8kBのような)ブロックによって出力をバッファします。

そのため、出力に4kB相当の文字が蓄積されたときにのみstdoutへの書き込みが開始されますが、これに/dev/randomはしばらく時間がかかります。

tr出力は端末に送られるので(端末のシェルプロンプトで実行している場合)、出力は行ごとにバッファされます。を削除し\nているので、書き込む行がなくなることはありません。代わりに、完全なブロックが蓄積されるとすぐに書き込みが行われます(出力が端末に送られない場合など)。

したがって、8kB(おそらく2ブロック以上)のデータを書き込むために十分な読み取りが完了するtrまで何も書き込まない可能性があります(最初のブロックにはおそらく改行文字、タブ文字、またはスペース文字が含まれるため)。strings/dev/random

私がこれを試しているこのシステムでは、/dev/random(12MiB onとは対照的に/dev/urandom)から平均3バイト/秒を得ることができるので、最良のシナリオでは(最初の4096バイト/dev/randomはすべて印刷可能です)、tr何も出力し始める22分前に話します。しかし、それはおそらく数時間になるでしょう(簡単なテストでは、strings1から2ブロックの読み取りごとにブロックを書き込むことがわかり、出力ブロックには改行文字の約30%が含まれているので、読む必要があると思います少なくとも3ブロック前trに4096文字が出力されます)。

それを回避するには、次のようにします。

< /dev/random stdbuf -o0 strings --bytes 1 | stdbuf -o0 tr -d '\n\t '

stdbuf LD_PRELOADトリックを介してコマンドのstdioバッファリングを変更するGNUコマンド(一部のBSDにもあります)です。

の代わりにstringstr -cd '[:graph:]'タブ、改行、スペースも除外することに注意してください。

CUTF-8文字で起こりうる将来の驚きを避けるために、ロケールを修正することもできます。


うわー印象的な説明。
Kiwy

2
すごい!素晴らしい説明と解決策。catパイプラインの最後でstdinをリダイレクトするのが好きではなかったので、私は常に「無駄に」使用していましたが、今では「プロセスを保存」し、読み取り可能なコマンドを使用できます。私の最終的な解決策は次の< /dev/random stdbuf -o0 tr -Cd '[:graph:]' | stdbuf -o0 head --bytes 32
アーロンJラング14

@AaronJLang、約良い点[:graph:]。私はそのことを忘れていました。
ステファンシャゼル14

@AaronJLangは、あなたが必要としないstdbufためにhead -c32あなたはそれがすぐにデータを書き込むことができるようにしたい場合を除き、それはそれを持っているとして、(代わりに、すぐにそれのと同じくらい1つの32バイトのチャンクのいくつかの塊のようにそれらを得た)
ステファンChazelas

2
私の意見では、作成者が使用するには/ dev / urandomで十分です。誰かがランダムに比べて、特にurandomがどのように機能するかについて興味があるなら、カーネルソースツリーのdrivers / char / random.cのドライバーの上部にあるコメントを読むことをお勧めします。コメントには、PRNGの分析とその実装が記載されています。願わくは、この論文が「urandomはrandomと比べてどれだけランダムであるか」という質問に答えることを願っています。こちらから入手可能:eprint.iacr.org/2012/251.pdf
etherfish

5

多くのセキュリティアプリケーションで乱数を生成するには、十分なエントロピーが必要です。エントロピーは、ランダム性の予測不可能性を測定します。決定論的プロセッサはエントロピーを生成できないため、エントロピーは外部から取得する必要があります。非決定論的動作を備えたハードウェアコンポーネント、またはユーザーアクションのタイミング(マウスをウィグリングする場所など)入って来る)。十分なエントロピーが利用可能になると、暗号化を使用して、事実上無制限の乱数ストリームを生成できます。

Linuxは、エントロピーをプールに蓄積し、暗号化を使用して/dev/randomとの両方で許容可能な乱数を生成し/dev/urandomます。違いは、プール内のエントロピーの量とは関係なく/dev/random、生成するすべてのバイトについてプール内のエントロピーの推定値を減らす非常に保守的なエントロピー計算を適用すること/dev/urandomです。

プール内のエントロピーの推定値が低すぎる場合、/dev/randomさらにエントロピーが蓄積されるまでブロックします。これ/dev/randomにより、出力を生成できるレートが大幅に低下する可能性があります。これがここで観察していることです。それは何の関係もありませんtr。ただしstrings、バッファリングを使用して出力を読み取る/dev/randomため、少なくとも1バイトの入力を生成するために、完全なバッファ(数KB)を読み取る必要があります。

/dev/urandomエントロピーは実際には知覚可能な方法で減少しないため、暗号化キーの生成には完全に受け入れられます。(ユニバースが存在するよりも長くマシンを実行し続けている場合、これらの考慮事項を無視することはできませんが、そうでない場合は良いことです。)良く/dev/urandomないケースは1つだけです。エントロピーを生成する時間はまだありませんでした。または、読み取り専用メディアから起動する新たに起動したシステムもありませんでした。

排除stringsブートチェーンからすると、おそらくあなたのプロセスをスピードアップします。以下trは非印刷文字をフィルタリングします:

</dev/random LC_ALL=C tr -dc '!-~'

ただし、十分なエントロピーを蓄積する時間がないシステムでパスワードを生成しないように注意する限り、ここ使用できます/dev/urandom。Linuxのエントロピープールのレベルを確認できます/proc/sys/kernel/random/entropy_avail(を使用する場合/dev/random、このファイルの図は控えめになり、おそらく非常によくなります)。


1

本当に予測不可能な乱数が絶対に必要な場合にのみ/dev/urandom、高品質の(擬似)乱数を取得するために使用する/dev/random必要があります。NSAのリソース以下の攻撃者は、クラックするのに非常に苦労/dev/urandomします(そして、ゴム製ホース暗号化を忘れないでください)。カーネルは、「本当にランダムな」バイトでバッファを満たし/dev/randomます。悲しいことに、それらが生成されるレートはそれほどからから多くのことを読んで、低い/dev/random だろうランダム性を待って失速します。

random.orgまたはそのパスワードジェネレーター、またはさまざまな多数のランダムパスワードジェネレーターの1つを使用することを検討するかもしれません。いくつかのコマンドラインのヒントについては、たとえばこのページご覧ください、しかし、彼らはあなたにアイデアを与える必要があります)、またはあなたはのようなものを使用することができますmkpasswd(1)(ここではFedora 19の一部expect-5.45-8.fc19.x86_64)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.