Java SecureRandomクラス

  • Java

  • link:/category/security-2/ [セキュリティ]

1. 前書き

この短いチュートリアルでは、暗号的に強力な乱数ジェネレーターを提供する_java.security.SecureRandom、_クラスについて学習します。

2. _java.util.Random_との比較

_java.util.Random_の標準JDK実装では、乱数を提供するためにhttps://en.wikipedia.org/wiki/Linear_congruential_generator[Linear Congruential Generator](LCG)アルゴリズムを使用します。 このアルゴリズムの問​​題は、暗号的に強力ではないことです。 つまり、生成された値ははるかに予測しやすいため、攻撃者はそれを使用してシステムを侵害する可能性があります。
この問題を解決するには、*セキュリティの決定に_java.security.SecureRandom_を使用する必要があります*。 *暗号的に強力な擬似乱数ジェネレータ*(https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator[CSPRNG])を使用して、暗号的に強力なランダム値を生成します。
LCGとCSPRNGの違いをよりよく理解するには、両方のアルゴリズムの値の分布を示す以下のチャートをご覧ください。
link:/uploads/secure_random_algorithms-100x50.png%20100w []
 

3. ランダム値の生成

_SecureRandom_を使用する最も一般的な方法は、* _ int _、_ long _、_ float _、_ double_または_boolean_値を生成することです*:
int randomInt = secureRandom.nextInt();
long randomLong = secureRandom.nextLong();
float randomFloat = secureRandom.nextFloat();
double randomDouble = secureRandom.nextDouble();
boolean randomBoolean = secureRandom.nextBoolean();
_int_値を生成するために、パラメーターとして上限を渡すことができます。
int randomInt = secureRandom.nextInt(upperBound);
さらに、_int、_ _double_、および_long_の*値のストリーム*を生成できます。
IntStream randomIntStream = secureRandom.ints();
LongStream randomLongStream = secureRandom.longs();
DoubleStream randomDoubleStream = secureRandom.doubles();
すべてのストリームについて、ストリームサイズを明示的に設定できます。
IntStream intStream = secureRandom.ints(streamSize);
また、起点(包括的)およびバインド(排他的)値:
IntStream intStream = secureRandom.ints(streamSize, originValue, boundValue);
ランダムバイトのシーケンスを生成することもできます。 _nextBytes()_関数は、ユーザー指定の_byte_配列を受け取り、ランダムな__byte__sで埋めます:
byte[] values = new byte[124];
secureRandom.nextBytes(values);

4. アルゴリズムの選択

*デフォルトでは、_SecureRandom_はSHA1PRNGアルゴリズム*を使用してランダム値を生成します。 _getInstance()_メソッドを呼び出すことにより、別のアルゴリズムを明示的に使用することができます。
SecureRandom secureRandom = SecureRandom.getInstance("NativePRNG");
_new_演算子を使用して_SecureRandom_を作成することは、_SecureRandom.getInstance(“ SHA1PRNG”)_と同等です。
Javaで利用可能なすべての乱数ジェネレーターは、https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecureRandom [公式ドキュメントページ]にあります。

5. 種

_SecureRandom_のすべてのインスタンスは、初期シードで作成されます。 ランダムな値を提供するためのベースとして機能し、新しい値を生成するたびに変化します。
_new_演算子を使用するか、_SecureRandom.getInstance()_を呼び出すと、https://tersesystems.com/blog/2015/12/17/the-right-way-to-use-securerandom/ [_ / devからデフォルトのシードを取得/ urandom_]。
シードをコンストラクターパラメーターとして渡すことで変更できます。
byte[] seed = getSecureRandomSeed();
SecureRandom secureRandom = new SecureRandom(seed);
または、すでに作成されたオブジェクトでセッターメソッドを呼び出します。
byte[] seed = getSecureRandomSeed();
secureRandom.setSeed(seed);
同じシードを使用して_SecureRandom_の2つのインスタンスを作成し、それぞれに対して同じメソッド呼び出しのシーケンスが作成されると、それらは*同一のシーケンスを生成して返すことに注意してください。

6. 結論

このチュートリアルでは、_SecureRandom_の仕組みと、ランダム値の生成に使用する方法を学びました。
いつものように、このチュートリアルで紹介するすべてのコードはhttps://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-security[GitHubで]にあります。