web-dev-qa-db-ja.com

OracleのJava.security.SecureRandomはどれほど安全にランダムか

昨年、弱い乱数発生器に起因する暗号化の悪用可能な弱点について多くのニュースがありました。場合によっては、開発者側の過失でしたが、それ以外の場合は インテリジェンス組織が安全なRNG生成のための標準を意図的に妨害している でした。

OracleのJavaVMで使用される SecureRandom 乱数ジェネレータの実装についてはどうですか?指定しない場合、どのアルゴリズムを使用していますか?そして、そのアルゴリズムとその実装は、暗号で使用するのに十分安全ですか?

10
Philipp

JDKの完全なソースコード(標準クラスだけでなく、Sun固有のクラスとC++ネイティブコードも)は、「研究ライセンス」の下で利用可能でしたが、JDK 1.6(I今日ではOpenJDKにアクセスするとします)。

_Java.security.SecureRandom_インスタンスを作成すると、デフォルトのPRNGが呼び出され、Sun固有のクラス_Sun.security.provider.SecureRandom_になることがわかります。

PRNG= isシードfrom _Sun.security.provider.SeedGenerator_は、OSが提供するものに依存しようと試み、つまり、Unixライクなシステム(Linuxなど)では_/dev/urandom_または_/dev/random_、WindowsではCryptoAPIのCryptGenRandom()が使用できません(またはJVMの構成から非アクティブ化されている場合)。シードは、OSがスレッド間でコンテキストを切り替えることができる速度を計ることによって抽出されます;これは、非常にまれにしかトリガーされないフォールバックメカニズムです。

シードは拡張されますカスタムであると思われるもので自家製PRNG SHA-1に基づいています。それはこのように動作します:

  • 160ビットの状態sがあり、これは20バイトであり、整数モジュロ2としても解釈されます。160リトルエンディアン規則を適用する。
  • 出力は20バイトのチャンクによって生成されます。
  • 次のチャンクを生成するにはc
    • c= SHA-1(s
    • s = s + c + 1 mod2160

sが確かにある時点で変更されることを保証するメカニズムがあります。 sが更新によって変更されていないように見える場合、その最初のバイトは強制的にインクリメントされます。これが呼び出されることはありません。そのような発生の確率は2です。-160特別なシードを使用して強制するには、SHA-1のプリイメージの抵抗を解除する必要がありますが、その方法はわかりません。

暗号的に言えば、これはひどいことではありません。約2の後でのみ、平均してサイクルに達するはずです。80チャンク、およびサイクルの平均長は同じでなければなりません。それはたくさんあります(約2,400億億ギガバイト)ので、それは良いことです。 SHA-1が ランダムOracle の場合、PRNGは、攻撃者が160ビットのスペースを列挙できない(現実的にはできない)限り、「明らかに」安全です。与えられたシードは、2400億以上の数十億ギガバイトを生成するために使用されません(そして、合理的な時間や不合理な時間では生成されません)。SHA-1はでないことを知っていますランダムなOracleですが、それでも十分にランダムに見えます。

個人的に、私はこれをPRNG暗号の使用に関する問題と見なしません。これには「マジック定数」がないため、バックドアされる可能性はほとんどありません。それの1つの悪い部分は非標準、したがって十分に研究されていません。


(ときに)Javaでformal暗号化(つまり、の実証に十分に適したランダム性)が必要な場合規制目的に適しています)、次に_Java.security.SecureRandom_を使用して初期シード(少なくとも16バイト)を生成し、HMAC_DRBGを実行します( NIST SP800-90A )(同じ出版物には不吉な名声のDual_EC_DRBGが含まれていますが、それでもHMAC_DRBGは暗号技術者によって細かくクリーンであると見なされています。

13
Tom Leek