# Is SecureRandom.ints() secure?

JavaSecurityRandom## Java Problem Overview

It is known that SecureRandom class provide strong cryptographic security for generated random number. `java.util.Random`

is insecure for the situation which requires cryptographic security. The typical usage of `SecureRandom`

is:

```
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
```

However, I met a case:

```
SecureRandom random = new SecureRandom();
int number = random.ints();
```

The method `ints()`

is inherited from the `java.util.Random`

class. I am confused when `SecureRandom`

which is a secure random number generator uses a method inherited from the insecure random number generator, whether it is secure?

## Java Solutions

## Solution 1 - Java

Yes it is secure.

Code examination of `java.util.Random`

shows that `ints()`

creates a spliterator that uses `internalNextInt(...)`

to generate the random integers. That in turn calls `nextInt()`

on `this`

. In the case of `java.security.SecureRandom`

, `nextInt()`

is overridden to generate a "secure" random number^{1}.

You can confirm this for yourself by looking at the source code.

^{1 - Of course, it doesn't actually make sense to call an integer or a sequence of integers "secure". And there are situations where SecureRandom may not have the properties that you require. (It depends on the actual RNG or PRNG implementation used by the class, the quality of the supplied seed or system provided entropy source, and so on.) But SecureRandom::ints() will generate a sequence of integers that has the same properties as if you made a sequence of SecureRandom::nextInt() calls on the same object. If the latter sequence is suitable for your purposes (whatever they are) then so is the former.}

## Solution 2 - Java

`Random.ints()`

is a method that returns an `IntStream`

. An `IntStream`

is neither secure nor insecure: it's a stream of numbers.

The "security" of the sequence of ints returned by the method depends on the implementation of the method. `SecureRandom`

generates its "random" values more securely than `Random`

. They share the same API, and thus you can use either in a given context depending upon your requirements.

So, the fact it inherits from an insecure class is irrelevant to the security: you can reasonably trust that the `SecureRandom`

class is as secure as the documentation says it is.

Consider an analogy with `HashSet`

: this makes no guarantees of the iterator ordering; however, `LinkedHashSet`

, a subclass of `HashSet`

*does* guarantee iterator ordering. The guarantee of `LinkedHashSet`

is consistent with the guarantee of `HashSet`

, because *a specific ordering* is one of the possible orderings that could be observed with "no guaranteed ordering" (after all, you have to return the elements in *some* order).

Similarly, `Random`

makes no guarantees about the security of the sequence of ints returned; `SecureRandom`

makes stronger guarantees. But there is no reason why the sequence of ints from a `SecureRandom`

couldn't also be returned by a `Random`

, by coincidence.

## Solution 3 - Java

Yes, `SecureRandom`

> provides a cryptographically strong random number generator (RNG).

One important factor for a secure RNG is the seed.

> Therefore any seed material passed to a SecureRandom object must be unpredictable, and all SecureRandom output sequences must be cryptographically strong, as described in RFC 4086: Randomness Requirements for Security.

Go ahead and use it. If you are interested in the details, read the JavaDoc which describes the various approaches used by implementations.

## Solution 4 - Java

#### ints method

Yes, it is secure, as long as `nextInt()`

is secure (for the number of integers retrieved from the stream).

According to the documentation of the `Random#ints()`

method:

> A pseudorandom `int`

value is generated as if it's the result of calling the method `nextInt()`

.

Now in turn, `Random#nextInt`

:

> The method `nextInt`

is implemented by class `Random`

as if by (returning) `next(32)`

`next(int)`

is a protected method that you cannot call, but which can be overridden in implementing classes.

Which in turn is implemented as `SecureRandom.next(32)`

* if you use an instance of SecureRandom rather than Random*:

> Generates an integer containing the user-specified number of pseudo-random bits (right justified, with leading zeros). This method overrides a `java.util.Random`

method, **and serves to provide a source of random bits to all of the methods inherited from that class** (for example, ** nextInt**,

`nextLong`

, and `nextFloat`

).So *in the end* a method of `SecureRandom`

is called, and if that's secure then the stream of random numbers is secure. Now to be honest, that statement is wrong in the sense that it isn't used for `nextBytes`

, but it is certainly used for any method that returns *number values*.

#### SecureRandom implementation

If you're already sure that the `SecureRandom`

that you use is secure, then you can stop reading here.

Now you'd think that it would end here, but `SecureRandom`

by itself does **not** implement a random **bit** generator. Instead, it simply depends on a particular service class within the configured provider which implements `SecureRandomSpi`

(Spi means Service Provider Interface, an abstract class a provider has to implement to deliver secure random data to instances of `SecureRandom`

). So in the end an invocation of `SecureRandomSpi#nextBytes()`

will have to be made within `SecureRandom#next(int)`

to retrieve the actual bits.

As stated for `Random#next(int)`

other methods that require numbers or streams of numbers should - in the end - all call this particular method. Now if this is indeed the case depends on the implementation of `Random`

, `SecureRandom`

. If the result is secure depends on the algorithm and the seeding provided by `SecureRandomSpi`

, the actual random bit generator that is used.

I've proven above that the result *should* be really be cryptographically random, assuming that `SecureRandom`

is cryptographically random. In the end only a full code review *for each implementation & version of Java* needs to be made to show that it is secure. That's outside of scope for StackOverflow though, you may need support from e.g. Oracle, IBM or Google to retrieve test documents and reviews, or you may perform such a review yourself for a particular implementation, of course. Most of it - if not all of it - is Open Source after all.

## Solution 5 - Java

Yes,

the previous solutions are using pseudo-random numbers. `SecureRandom`

is a cryptographically strong random number generator.

The implementation only differs slightly from the ones before. Frankly speaking, it is a drop-in replacement for Random:

```
public static void main(String[] args) {
SecureRandom current = new SecureRandom();
// [0, 101)
System.out.println(current.nextInt(101));
System.out.println(current.nextInt(101));
}
```

For more see Java Random Number Generation.