メインコンテンツまでスキップ

7.1. Complete Randomness Generators (完全なランダム性生成器)

7.1. Complete Randomness Generators (完全なランダム性生成器)​

以下に 3 つの標準を説明します。2 つの古い標準は, 64 ビットのブロックと鍵サイズの制限を持つ DES を使用していますが, 同等以上に強力な混合関数を代用できます [DES]。3 番目は SHA-1 [SHA*] に基づくより現代的で強力な標準です。最後に, 広く展開されている現代の UNIX および Windows 乱数生成器を説明します。

7.1.1. US DoD Recommendations for Password Generation (米国国防総省のパスワード生成推奨事項)​

米国国防総省は, パスワード生成に関する特定の推奨事項を持っています [DoD]。次のように出力フィードバックモード [MODES] で米国データ暗号化標準 [DES] を使用することを提案しています:

システムクロック,
システム ID,
ユーザー ID, および
日付と時刻から決定された初期化ベクトルを使用します;

システム割り込みレジスタ,
システムステータスレジスタ, および
システムカウンタから決定された鍵を使用します; そして,

平文として, システム管理者が入力した 8 文字の ASCII バイトなどの
外部的にランダムに生成された 64 ビット量を使用します。

パスワードは, 64 ビット出力フィードバックモードで DES によって生成された 64 ビット "暗号文" から計算できます。人間がパスワードを覚える必要がある場合, これらの 64 ビットから必要な数のビットを取り, 発音可能な単語, フレーズ, または他の形式に拡張できます。

7.1.2. The /dev/random Device (/dev/randomデバイス)​

UNIX オペレーティングシステムのいくつかのバージョンは, カーネル常駐乱数生成器を提供します。これらの生成器の一部は, 通常のシステム操作中にカーネルによってキャプチャされたイベントを使用します。

たとえば, Linux のいくつかのバージョンでは, 生成器は 4 バイトの 128 ワードとして表される 512 バイトのランダムプールで構成されています。ディスクドライブ割り込みなどのイベントが発生すると, イベントの時刻がプールに XOR され, プールは 128 次の原始多項式でかき混ぜられます。プール自体はリングバッファとして扱われ, 新しいデータが (多項式でかき混ぜられた後) プール全体に XOR されます。

エントロピーをプールに追加する各呼び出しは, 入力に含まれる可能性の高い真のエントロピーの量を推定します。プール自体には, プールの全体的なエントロピーを推定するアキュムレータが含まれています。

入力イベントは, 以下にリストされているいくつかのソースから来ます。残念ながら, 人間のオペレーターがいないサーバーマシンの場合, 1 番目と 3 番目は利用できず, その場合エントロピーはゆっくりと追加される可能性があります。

  1. キーボード割り込み。割り込みの時刻とスキャンコードがプールに追加されます。これは実質的に, キーストローク間到着時間を測定することによって人間のオペレーターからエントロピーを追加します。

  2. ディスク完了およびその他の割り込み。人によって使用されているシステムは, おそらく予測困難なディスクアクセスのパターンを持つでしょう。(ただし, すべてのディスクドライバーが有用であるのに十分な精度でこのタイミング情報をキャプチャすることをサポートしているわけではありません。)

  3. マウスの動き。タイミングとマウスの位置が追加されます。

ランダムバイトが必要な場合, プールは SHA-1 [SHA*] でハッシュされ, 返されるランダム性のバイトが得られます。SHA-1 の出力 (20 バイト) よりも多くのバイトが必要な場合, ハッシュされた出力はプールにかき混ぜられ, 次の 20 バイトを取得するために新しいハッシュが実行されます。バイトがプールから削除されると, エントロピーの推定値は対応して減少します。

システム起動時に合理的にランダムなプールを確保するために, 標準的な起動およびシャットダウンスクリプトは, シャットダウン時にプールをディスクファイルに保存し, システム起動時にこのファイルを読み取ります。

2 つのユーザー公開インターフェイスがあります。/dev/random はプールからバイトを返しますが, 推定エントロピーがゼロに低下するとブロックします。イベントからプールにエントロピーが追加されると, /dev/random を介してより多くのデータが利用可能になります。このような /dev/random デバイスから取得されたランダムデータは, 長期鍵の鍵生成に適しています。十分なランダムビットがプールにあるか, 合理的な時間内に追加される場合です。

/dev/urandom は /dev/random のように動作します。ただし, ランダムプールのエントロピー推定値がゼロに低下してもデータを提供します。これは, ブロックしてより多くのランダムビットを待つことが受け入れられないセッション鍵または他の鍵生成タスクに適切である可能性があります。プールのエントロピー推定値が小さい場合でもデータを取り続けるリスクは, 攻撃者が SHA-1 を逆にできる場合, 過去の出力が現在の出力から計算可能である可能性があることです。SHA-1 が非可逆的であるように設計されていることを考えると, これは合理的なリスクです。

Linux, Solaris, または上記のようなコードを備えた他の UNIX システムで乱数を取得するには, アプリケーションが行う必要があるのは, /dev/random または /dev/urandom を開き, 望ましい数のバイトを読み取ることだけです。

(Linux ランダムデバイスは Theodore Ts'o によって書かれました。これは PGP 2.X および PGP 3.0 (別名 PGP 5.0) の乱数生成器に緩やかに基づいていました。)

7.1.3. Windows CryptGenRandom (Windows CryptGenRandom)​

広く展開されている Windows オペレーティングシステムのユーザーに対する Microsoft の推奨事項は, 一般に CryptAPI 暗号サービスプロバイダで CryptGenRandom 擬似乱数生成呼び出しを使用することです。これは, 暗号サービスプロバイダライブラリへのハンドル, 呼び出し側がエントロピーを提供でき生成された擬似ランダム性が返されるバッファへのポインタ, およびランダム性のオクテット数の指示を取ります。

Windows CryptAPI 暗号サービスプロバイダは, すべてのユーザーでシード状態変数を保存します。CryptGenRandom が呼び出されると, これは呼び出しで提供されるランダム性と, プロセス ID, スレッド ID, システムクロック, システム時刻, システムカウンタ, メモリステータス, 空きディスククラスタ, およびハッシュされたユーザー環境ブロックなどのさまざまなシステムおよびユーザーデータと組み合わされます。このデータはすべて SHA-1 に供給され, 出力は RC4 鍵ストリームをシードするために使用されます。その鍵ストリームは, 要求された擬似ランダムデータを生成し, ユーザーのシード状態変数を更新するために使用されます。

Windows ".NET" のユーザーは, RNGCryptoServiceProvider.GetBytes メソッドインターフェイスを使用する方が簡単であることがわかるでしょう。

詳細については, [WSC] を参照してください。