回答:
Javaアプリケーションでは、java.security.SecureRandomクラスを使用して、暗号学的に強力な疑似乱数ジェネレータ(CSPRNG)を使用することにより、暗号学的に強力なランダム値を生成できます。java.util.Randomクラスの標準JDK実装は、暗号的に強力であるとは見なされません。
Unixライクなオペレーティングシステムには/dev/random
、デバイスドライバーやその他のソースから収集された環境ノイズにアクセスする擬似乱数を提供する特別なファイルがあります。ただし、要求よりもエントロピーが少ない場合はブロックします。/dev/urandom
ブート後に疑似乱数ジェネレータシードがエントロピーで完全に初期化されていなくても、通常はブロックしません。まだ3番目の特殊ファイルが/dev/arandom
あり、ブート後にシードが十分なエントロピーで安全に初期化されるまでブロックし、その後再びブロックすることはありません。
デフォルトでは、JVMはSecureRandomクラスをを使用してシードする/dev/random
ため、Javaコードが予期せずブロックする可能性があり ます。-Djava.security.egd=file:/dev/./urandom
Javaプロセスの開始に使用されるコマンドライン呼び出しのオプションは、/dev/urandom
代わりに使用するようにJVMに指示します。
余分な/./
ものは、JVMがSHA-1をPRNG(Pseudo Random Number Generator)の基礎として使用するSHA1PRNGアルゴリズムを使用するようにするようです。/dev/urandom
が指定されている場合に使用されるNativePRNGアルゴリズムよりも強力です。
最後に、/dev/urandom
疑似乱数ジェネレータであるPRNGであり/dev/random
、「真の」乱数ジェネレータであるという神話があります。これは単に真実では/dev/random
ありません。両方とも/dev/urandom
同じCSPRNG(暗号的に安全な疑似乱数ジェネレータ)によって供給されます。:それぞれのプールは、いくつかの見積もり、異なっによると、エントロピーが不足のみ動作/dev/random
しながら、ブロック/dev/urandom
しません。
エントロピーの不足はどうですか?それは問題ではありません。
「ランダムに見える」ことは、多くの暗号化ビルディングブロックの基本的な要件であることがわかります。また、暗号化ハッシュの出力を取得する場合、暗号がそれを受け入れるように、ランダムな文字列と区別できないようにする必要があります。これがSHA1PRNGアルゴリズムを使用する理由です。SHA1PRNGアルゴリズムは、シードと共にハッシュ関数とカウンターを使用するためです。
いつ適用されることになっていますか?
いつも、私は言うでしょう。
出典:
https
: //gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom
編集2020年4月:
コメントには、Java 8 でのSecureRandomクラスの動作の変更が記載されています。
SHA1PRNGとNativePRNGは、java.securityファイルのSecureRandomシードソースプロパティを適切に尊重するように修正されました。(file:/// dev / urandomおよびfile:/ dev /./ urandomを使用するあいまいな回避策は不要になりました。)
これは、上記の「ソース」セクションで参照されているテストによってすでに指摘されていました。Java 8のSecureRanomで/./
使用されるアルゴリズムをNativePRNGからSHA1PRNGに変更するには、追加が必要です。
しかし、私は共有したいいくつかのニュースを持っています。JEP-273に従って、Java 9以降、SecureRandomクラスはNIST 800-90Ar1で説明されている3つの確定的ランダムビットジェネレーター(DRBG)メカニズムを実装しています。これらのメカニズムは、SHA-512およびAES-256と同等の強力な最新のアルゴリズムを実装しています。
JDKには2種類のSecureRandom実装がありました。
/dev/{u}random
Unixでの読み取りやWindowsでのCryptoAPIの使用などのOSデバイスに基づいています。LinuxとWindowsの最新リリースはすでにDRBGをサポートしていますが、古いリリースと組み込みシステムはサポートしていない場合があります。一方、Java 13 Security Developer's Guideには、まだ
LinuxおよびmacOSでは、java.securityのエントロピー収集デバイスが
file:/dev/urandom
またはfile:/dev/random
に設定されている場合、SHA1PRNGよりNativePRNGが優先されます。それ以外の場合は、SHA1PRNGが推奨されます。
新しいDRBGメカニズムが以前のPRNGとどのように連携するかを明確にするために、macOS(Darwin)でAdoptOpenJDK(ビルド13.0.2 + 8)を使用していくつかのテストを実行します。結果は次のとおりです。
file:/ dev / random
プロバイダーの優先順位:
SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG
file:/ dev / urandom
プロバイダーの優先順位:
SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG
file:/ dev /./ urandom
プロバイダーの優先順位:
SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG
結論:
使用-Djava.security.egd=file:/dev/./urandom
するプラットフォームに関係なく、使用可能な最も強力なSecureRandom実装を確実に活用しながら、コードが予期せずブロックされるのを回避することをお勧めします。
/dev/urandom
する/dev/urandom
一方で、によって供給されるNativePRNG を選択/dev/./urandom
します(これもによって供給されます/dev/urandom
)。Java9以降、/dev/./urandom
ソースが指定されている場合、DRBGが優先されます。
JDK 8以降を使用している場合、これは不要になりました
この問題はJavaによって修正され、ここにいくつかのリンクがあります
概要
SHA1PRNGとNativePRNGは、java.securityファイルのSecureRandomシードソースプロパティを適切に尊重するように修正されました。(file:/// dev / urandomおよびfile:/ dev /./ urandomを使用するあいまいな回避策は不要になりました。)
詳細(ページでランダムを検索):
https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html
https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html
これは、linux /dev/random
と/dev/urandom
乱数ジェネレータの違いに関連しています。
このリンクから取得
Javaバグ6202721では、/ dev / urandomが指定されていたとしても(2004年頃)/ dev / urandomが適切に機能していなかったため、java.security.SecureRandomは/ dev / urandomではなく/ dev / randomを使用すると述べています。/ dev / urandomが非常にうまく機能するようになったため、このバグは元に戻されていません。したがって、/ dev /./ urandomを使用して設定を覆い隠し、/ dev / randomではなくSHA1PRNGの使用を強制することで、偽造する必要があります。
あなたの質問に答えるために
いつ適用されることになっていますか?
上記のリンクに基づくと、これはJavaバージョン5以降に固有のものであり、2004年にLinuxシステムでの/ dev / urandomの問題に起因します。