[解決済み】 java.util.Random と java.security.SecureRandom の違いについて
質問
私のチームは、ランダムなトークンを生成するサーバーサイドのコード(Java)を渡されましたが、私は同じことについて質問があります。
これらのトークンの目的は、セッションID、パスワードリセットリンクなどに使用される、かなり機密性の高いものです。そのため、誰かに推測されたり、ブルートフォースで実行されたりしないように、暗号学的にランダムである必要があります。トークンは64ビットの長さで、quot;long"です。
現在、このコードでは
java.util.Random
クラスがこれらのトークンを生成します。そのため
ドキュメント
に対して
java.util.Random
には、次のように明記されています。
java.util.Randomのインスタンスは暗号学的に安全ではありません。セキュリティに敏感なアプリケーションで使用するための暗号的に安全な擬似乱数生成器を取得するには、代わりにSecureRandomを使用することを検討してください。
しかし、現在のコードでは
java.util.Random
をインスタンス化することです。
java.security.SecureRandom
クラスを作成し
SecureRandom.nextLong()
メソッドでシードを取得し、それを使って
java.util.Random
クラスがあります。次に
java.util.Random.nextLong()
メソッドを使用してトークンを生成します。
そこで質問なのですが
java.util.Random
を使用してシードされています。
java.security.SecureRandom
? を使用するようにコードを修正する必要がありますか?
java.security.SecureRandom
はトークンの生成にのみ使用されるのですか?
現在、コードのシードが
Random
起動時に一度だけ
解決方法は?
Oracle JDK 7の標準的な実装では、線形合同生成器と呼ばれるものを使用して、ランダムな値を生成するために
java.util.Random
.
より抜粋
java.util.Random
のソースコード (JDK 7u2) のコメントから。
protected int next(int bits)
これはランダムな値を生成するものです。
これは、線形合同擬似乱数生成器である。 でD. H. Lehmerが定義し、Donald E. Knuthが記述しています。 コンピュータ・プログラミングの技術 第3巻 半数アルゴリズム 3.2.1項を参照。
線形合同発電機の予測可能性
Hugo Krawczykは、これらのLCGがどのように予測されるかについて、かなり良い論文を書いています("How to predict congruential generators")。もしあなたがラッキーで興味があれば、まだウェブ上でその無料ダウンロード版を見つけることができるかもしれません。そして、もっとたくさんの研究があり、明らかに次のようなことを示しています。 決して セキュリティクリティカルな目的でLCGを使用する。これは、あなたの乱数 は セッションIDなどには不要なものです。
線形合同発電機の壊し方
攻撃者はLCGが一巡するのを待つ必要があるという仮定は間違っています。最適なサイクル(その再帰関係における係数m)であっても、フルサイクルよりもはるかに短い時間で将来の値を予測することは非常に簡単です。結局のところ、解く必要があるのはモジュール式の束だけで、LCGの出力値を十分に観測した後はすぐに簡単になるのである。
種が良くても、セキュリティは向上しません。で生成された乱数値で種を蒔いたとしても、それは単に問題ではありません。
SecureRandom
あるいは、サイコロを数回振って値を出すことも可能です。
攻撃者は、観測された出力値から単純に種を計算する。これには
かなり少ない
の場合、2^48よりも時間がかかる。
java.util.Random
. 不信心な人はこれを試してみてください
実験
を予測することができることが示されています。
Random
の出力は、時間にしておよそ2^16の間にたった2つ(!)の出力値を観測するだけです。今すぐ乱数の出力を予測するには、現代のコンピュータでは1秒もかからない。
まとめ
現在のコードを置き換えます。使用方法
SecureRandom
のみです。そうすれば、少なくとも、結果が予測しにくいという保証が少しは得られるでしょう。もしあなたが暗号的に安全なPRNGの特性を求めるなら(あなたの場合はそれが目的です)、次のようにしなければなりません。
SecureRandom
だけです。本来の使い方を巧妙に変えようとすると、ほとんどの場合、安全性の低いものができてしまう...。
関連
-
[解決済み] javac ソースファイルが見つかりません
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] JavaScriptで2つの数値の間の乱数を生成する
-
[解決済み] 0から9までのランダムな整数を生成する
-
[解決済み] StringBuilderとStringBufferの違いについて
-
[解決済み] wait()とsleep()の違いについて
-
[解決済み] JDKとJREの違いは何ですか?
-
[解決済み】HashMap、LinkedHashMap、TreeMapの違いについて
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Jdbctemplate の文字列に対するクエリです。EmptyResultDataAccessException: 不正な結果サイズ:期待値1、実際0
-
[解決済み] Java - JTextFieldが空かどうかを確認する
-
[解決済み] Firebase クラスにシリアライズするプロパティが見つからない
-
[解決済み] ボタンでTextFieldをクリアする(Java)
-
[解決済み] Cloneable throws CloneNotSupportedException
-
[解決済み] java.lang.ClassCastException: java.util.Arrays$ArrayList は java.util.ArrayList にキャストできません。
-
[解決済み] javac ソースファイルが見つかりません
-
[解決済み] 要素 'beans' の宣言が見つかりません。
-
[解決済み] ファイルを作成せずに、ファイルが存在するかどうかをチェックする
-
[解決済み] Eclipseでクラスとそれに対応するファイルの名前を変更する方法は?