Difference between nextXXX() and generateSeed() function in SecureRandom?
Asked Answered
T

3

8

What is the difference between functions nextXXX() - such as like nextInt(), nextFloat() and nextBytes() - and generateSeed(int numBytes): byte[] in the SecureRandom class of Java?

In what way does "the seed generation algorithm" in generateSeed differ from the secure random generator itself?

Tops answered 9/8, 2014 at 16:10 Comment(5)
Have you read the JavaDocs? They seem quite clear to me ...Cachucha
@Cachucha Thanks for your comment, yes I read the java doc before posting this question. It would be really helpful, if you explain the differenceTops
Why? It would be really helpful if you would explain what part of the Javadoc you don't understand. The difference is that they aren't the same.Venita
@EJP Fixed the question, the JavaDoc isn't that clear on what generateSeed does in my opinion, "the seed generation algorithm" is not specified at all.Viaticum
@owlstead Thanks for editing question for more clarity, yes I was looking for the seed generation algorithmTops
V
12

generateSeed() does not use any bytes generated by the random number generator. Instead, it is just a pass through to the entropy source that the SecureRandom implementation uses to seed itself when and if it is seeding itself.


So for instance calling the following code on an Oracle provided Java SE:

// initSeed is just zero valued bytes
byte[] initSeed = new byte[16];

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(initSeed);

byte[] seed = secureRandom.generateSeed(16);

byte[] data = new byte[16];
secureRandom.nextBytes(data);

System.out.printf("Seed: %s%n", Hex.toHexString(seed));
System.out.printf("Data: %s%n", Hex.toHexString(data));

Will actually give back different values for seed, and always the same value for data. In other words, the generateSeed uses the operating system to ask for 16 bytes of entropy, while the random number generator is only seeded with the initSeed and thus will always generate the same stream of pseudo random numbers.

Warning: this is just to illustrate the point; you should not rely on any SecureRandom instance to return anything but random bytes. The behavior with regards to setSeed differs per implementation. The Oracle "SHA1PRNG" provider uses it as the only seed, others may choose to mix it into the state of the PRNG (for instance later Android implementations will always generate random data).

Viaticum answered 9/8, 2014 at 16:39 Comment(0)
H
3

Random number functions depend on an initial value from which they generate a sequence of random numbers (read up on PRNG - Pseudo Random Number Generation). The next functions will return the next number generated from that initial value (the seed). generateSeed() will generate a new initial value for a PRNG to use.

Haberdasher answered 9/8, 2014 at 16:14 Comment(3)
Doesn't restart anything on my machine. You can use it to start up or seed another generator though.Viaticum
This was meant to be a really generic answer, sorry. It seemed like the OP didn't quite understand the concept, rather than the implementation of it.Haberdasher
OK, but that last line is simply not correct, it doesn't restart anything by itself. Happy to upvote if you fix it.Viaticum
B
0

In fact, nextXYZ() and generateSeed() do the exactly same thing, most often 😏

SecureRandom.nextBytes() and SecureRandom.generateSeed() actually are just thin wrappers that forward the call to SecureRandomSpi.engineGenerateSeed() and SecureRandomSpi.engineNextBytes(), respectively, which contain the actual implementation.

The concrete implementation of SecureRandomSpi depends on the selected algorithm, of course! However, for the default SecureRandom algorithm on the Windows platform (i.e. "Windows-PRNG"), we can see from the source code that engineNextBytes() and engineGenerateSeed() do the exactly same thing: They both call a native method named PRNG.generateSeed(), which is a C++ function that ends up calling the Win32 API function CryptGenRandom() from the OS 😲

See here for details:


The implementation of the "NativePRNG" algorithm, which is the default algorithm on Linux/Unix and MacOS, is a bit more convoluted. But, essentially, engineNextBytes() and engineGenerateSeed() once again both end up in the same method – which is RandomIO.readFully(). That method simply reads the "random" bytes from an InputStream, which has been associated with /dev/[u]random, i.e. the kernel random number source.

See here for details:


All of the other [Secure]Random.nextXYZ() methods, such as nextInt(), nextLong() or nextDouble(), call an internal method named next(), which provides the request number of random bits. And, not much surprising, the next() method ends up calling nextBytes() – and therefor, in case of SecureRandom, invokes SecureRandomSpi.engineNextBytes() 😂

Bigoted answered 31/10, 2023 at 23:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.