要約
OpenSSL が利用する擬似乱数生成器関連のモジュールです。
暗号と乱数
OpenSSL では、鍵を生成するためなどに乱数を用いています。例えば RSA では巨大(512bitや1024bitなど)な素数の組を乱数で生成し、そこから公開鍵、秘密鍵のペアを計算します。鍵は他人に知られてはならないため、その乱数は外部からの推論が不可能な良い性質を持っている必要があります。このようなメソッドには以下のものがあります。
- OpenSSL::PKey::RSA.generate
- OpenSSL::PKey::DSA.generate
- OpenSSL::PKey::DH.generate
- OpenSSL::Cipher#random_key
そのような乱数は適切な実装を持つ擬似乱数生成器に適切なシードを渡すことによって実現できます。
OpenSSL にはそのような擬似乱数生成器が実装されています。そして、この擬似乱数生成器は OpenSSL の様々なモジュールから利用されています。上に挙げた鍵生成メソッドの他に、
などでも利用されます。
擬似乱数生成器は適切なシードを与えられなければ正しく動作しません。 OpenSSL にはそのための API
が存在します。これらの API を模式的に説明すると、以下のようになります。
- シードの各ビットは統計的な乱雑さ、予測不可能性を持ち、ビット列の 乱雑さはエントロピーという量(単位は bit, 8bit = 1byte) で量ることができる。
- 特にシードのすべてのビットが完全にランダムである場合には、 エントロピーの大きさとシードのビット数は一致する。逆に シードのすべてのビットがある意味で既知ならば、 エントロピーは 0 である。
- 擬似乱数生成器にエントロピーを追加することによって 乱数生成器から得られる乱数がより予測不可能になる。
エントロピー源には良いものと悪いものがあります。例えば現在時刻(Unix time)はエントロピー源としては悪いです。なぜなら予測不可能なのはせいぜい秒の部分のみであり、上位のビットは予測可能だからです。そこに含まれるエントロピー量を適切に評価できるならばシードとして利用できますが、通常はもっと良いエントロピー源があるはずです。 Linux であれば /dev/random が適当なエントロピー源となるでしょう。
OpenSSL では EGD(Entropy Gathering Daemon)からエントロピーを取得することもできます。適切なエントロピー源を提供していない OS ではこのような方法でエントロピー源を用意する必要があるかもしれません。
実際のところ、OpenSSL バージョンによっては OS が提供するエントロピー源から必要な量のエントロピーを得るよう実装してあるため、これらの API を使ってエントロピーを追加する必要はない場合が多いでしょう。ただし、 OS によっては OpenSSL が利用可能なエントロピー源を見つけられない場合があり、その場合はこれらのメソッドで明示的にエントロピーを追加する必要があるでしょう。
目次
- モジュール関数
モジュール関数
egd(filename) -> true
[permalink][rdoc][edit]-
EGD(Entropy Gathering Daemon) からエントロピーを得、乱数生成器に追加します。
filename で指定した Unix domain socket から EGD に問い合わせ、 255 バイト分のエントロピーを取得します。 OpenSSL::Random.egd_bytes(filename, 255) と同じです。
- [PARAM] filename:
- EGD のソケットのファイル名
- [EXCEPTION] OpenSSL::Random::RandomError:
egd_bytes(filename, length) -> true
[permalink][rdoc][edit]-
EGD(Entropy Gathering Daemon) から length バイト分のエントロピーを得ます。
filename で指定した Unix domain socket から EGD に問い合わせ、指定した大きさのエントロピーを乱数生成器に追加します。
- [PARAM] filename:
- EGD のソケットのファイル名
- [PARAM] length:
- 読み込むバイト数
- [EXCEPTION] OpenSSL::Random::RandomError:
- [EXCEPTION] OpenSSL::Random::RandomError:
load_random_file(filename) -> true
[permalink][rdoc][edit]-
ファイルを読み込み、その内容をエントロピー源として乱数生成器に渡します。
エントロピーの推定量はファイルのバイト数と同じであると見なします。
OpenSSL::Random.seed(File.read(filename)) と同じです。
- [PARAM] filename:
- 読み込むファイル名
- [EXCEPTION] OpenSSL::Random::RandomError:
- ファイルの読み込みに失敗した場合に発生します
- [EXCEPTION] OpenSSL::Random::RandomError:
pseudo_bytes(len) -> String
[permalink][rdoc][edit]-
暗号論的な予測不可能性を持たない(が高速な) 乱数生成器によって、 len バイトのランダムなバイト列を返します。
- [PARAM] len:
- 必要なランダムバイト列の長さ
random_add(str, entropy) -> self
[permalink][rdoc][edit]-
乱数生成器にエントロピーを追加します。
entropy には str が持っているエントロピーの予測値(の下限)をバイト単位で渡します。
- [PARAM] str:
- 予測不可能な内容の文字列
- [PARAM] entropy:
- str が持っているエントロピーの予測値(バイト単位)の浮動小数点数
random_bytes(len) -> String
[permalink][rdoc][edit]-
暗号論的な予測不可能性を持つ乱数生成器によって、 len バイトのランダムなバイト列を返します。
- [PARAM] len:
- 必要なランダムバイト列の長さ
seed(str) -> str
[permalink][rdoc][edit]-
乱数生成器にエントロピーを「エントロピー予測値 = str のバイト数」として追加します。
OpenSSL::Random.random_add(str, str.size) と同じです。
- [PARAM] str:
- 予測不可能な内容の文字列
[SEE_ALSO] OpenSSL::Random.#random_add
status? -> bool
[permalink][rdoc][edit]-
乱数生成器内のエントロピーが十分である場合に true を返します。
write_random_file(filename) -> true
[permalink][rdoc][edit]-
乱数生成器で生成された 1024 バイトのランダムなバイト列をファイルに書き込みます。
これで出力したランダムなバイト列はあとで乱数生成器を初期化するのに使えます。リブート直後などシステムからのエントロピーが少ない場合に利用できます。
このファイルは利用者以外には読めないように保存しなければなりません。部外者がこのファイルを読めることはセキュリティ上の問題を引き起します。
- [PARAM] filename:
- 書き込むファイルの名前
- [EXCEPTION] OpenSSL::Random::RandomError:
- ファイルの書き出しに失敗した場合に発生します