1. 序章

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

2. java.util.Randomとの比較

java.util.Random の標準JDK実装は、線形合同法(LCG)アルゴリズムを使用してランダムな数値を提供します。 このアルゴリズムの問題は、暗号的に強力ではないことです。 つまり、生成された値ははるかに予測可能であるため、攻撃者はそれを使用してシステムを危険にさらす可能性があります。

この問題を解決するには、セキュリティの決定にjava.security.SecureRandomを使用する必要があります暗号的に強い疑似乱数ジェネレータ CSPRNG )を使用して、暗号的に強い乱数を生成します。

LCGとCSPRNGの違いをよりよく理解するには、両方のアルゴリズムの値の分布を示す以下のグラフを参照してください。

 

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);

さらに、[X21X] int、 double 、およびlongの値のストリーム生成できます。

IntStream randomIntStream = secureRandom.ints();
LongStream randomLongStream = secureRandom.longs();
DoubleStream randomDoubleStream = secureRandom.doubles();

すべてのストリームについて、ストリームサイズを明示的に設定できます。

IntStream intStream = secureRandom.ints(streamSize);

また、origin(包括的)値とbound(排他的)値も同様です。

IntStream intStream = secureRandom.ints(streamSize, originValue, boundValue);

ランダムバイトのシーケンスを生成することもできます。 nextBytes()関数は、ユーザー指定の byte 配列を受け取り、ランダムbyteで埋めます。

byte[] values = new byte[124];
secureRandom.nextBytes(values);

4. アルゴリズムの選択

デフォルトでは、SecureRandomはSHA1PRNGアルゴリズムを使用してランダムな値を生成します。 getInstance()メソッドを呼び出すことにより、別のアルゴリズムを明示的に使用させることができます。

SecureRandom secureRandom = SecureRandom.getInstance("NativePRNG");

new演算子を使用してSecureRandomを作成することは、 SecureRandom.getInstance( “SHA1PRNG”)と同等です。

Javaで利用可能なすべての乱数ジェネレーターは公式ドキュメントページにあります。

5. シード

SecureRandom のすべてのインスタンスは、初期シードを使用して作成されます。 これは、ランダムな値を提供するためのベースとして機能し、新しい値を生成するたびに変更されます。

new 演算子を使用するか、 SecureRandom.getInstance()を呼び出すと、 / dev /urandomからデフォルトシードが取得されます。

シードをコンストラクターパラメーターとして渡すことで、シードを変更できます。

byte[] seed = getSecureRandomSeed();
SecureRandom secureRandom = new SecureRandom(seed);

または、すでに作成されているオブジェクトに対してsetterメソッドを呼び出すことによって:

byte[] seed = getSecureRandomSeed();
secureRandom.setSeed(seed);

同じシードを使用してSecureRandomの2つのインスタンスを作成し、それぞれに対して同じシーケンス呼び出しを行うと、生成され、同じ番号のシーケンスが返されることに注意してください。

6. 結論

このチュートリアルでは、 SecureRandom がどのように機能し、ランダムな値を生成するためにそれを使用する方法を学びました。

いつものように、このチュートリアルで提示されるすべてのコードは、GitHubにあります。