Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I'd like to understand Java's SecureRandom object

While doing a beginner's crypto course I'm trying to get to grips with Java's SecureRandom object. What I think I understand is that:

a) No matter how long a sequence of random numbers you know, there is no way of predicting the next random number in the sequence.

b) No matter how long a sequence of random numbers you know, there is no way of knowing which seed was used to start them off, other than brute force guesswork.

c) You can request secure random numbers of various sizes.

d) You can seed a newly-created SRNG with various different-sized values. Every newly-created SRNG you create and seed with the same value will produce the same sequence of random numbers.

I should add that I'm assuming that this code is used on Windows:

Random sr = SecureRandom.getInstance("SHA1PRNG", "SUN");

Is my basic understanding correct? Thanks in advance.

I have some further questions for anyone who's reasonably expert in crypto. They relate to seeding a SRNG as opposed to letting it seed itself on first use.

e) What difference, if any, does it make to the random numbers generated, if you seed a SRNG with a long integer as opposed to an array of 8 bytes?

f) If I seed a SRNG with, say, 256 bytes is there any other seed that can produce the same sequence of random numbers?

g) Is there some kind of optimum seed size? It seems to me that this might be a meaningless question.

h) If I encrypt a plaintext by seeding a SRNG with, say, 256 bytes then getting it to generate random bytes to XOR with the bytes in the plaintext, how easy would it be for an eavesdropper to decrypt the resulting ciphertext? How long might it take? Am I right in thinking that the eavesdropper would have to know, guess, or calculate the 256-byte seed?

I've looked at previous questions about SecureRandom and none seem to answer my particular concerns. If any of these questions seem overly stupid, I'd like to reiterate that I'm very much a beginner in studying this field. I'd be very grateful for any input as I want to understand how Java SecureRandom objects might be used in cryptography.

like image 546
Garry Knight Avatar asked Oct 01 '22 23:10

Garry Knight


2 Answers

d) This is true for a PRNG. It is not always true for a CSRNG. Read the Javadoc for SecureRandom.setSeed(): "The given seed supplements, rather than replaces, the existing seed. Thus, repeated calls are guaranteed never to reduce randomness."

Any reasonable CSRNG will have "invisible" sources of entropy that you cannot explicitly control, often various internal parameters taken from the Operating System level. Hence there is more seeding than any number you explicitly pass to the RNG.

like image 51
rossum Avatar answered Oct 04 '22 19:10

rossum


OK, in order:

a) correct

b) correct

c) correct, you can even request a number in a range [0, n) using nextInt(n)

d) as good as correct: the implementation of SHA1PRNG is not publicly defined by any algorithm and there are indications that the implementation has changed in time, so this is only true for the Sun provider, and then only for a specific runtime configuration

e) as the API clearly indicates that all the bytes within the long are used ("using the eight bytes contained in the given long seed") there should not be any difference regarding the amount of entropy added to the state

Note that a quick check shows that setSeed(long) behaves entirely different from setSeed(byte[]) with the main difference that the seed of the long value is always mixed in with randomness retrieved from the system, even if it is the first call after the SecureRandom instance is constructed.

f) yes - an infinite number of seeds generate the same stream; since a hash function is used, it will be impossible to find one though

g) if you mix in additional entropy, then the more entropy the better, but there is no minimum; if you use it as the only seed then you should not start off with less than 20 bytes of seed, that is: if you want to keep the seed to the same security constraints as the inner state of the PRNG

And I would add that if you use less than 64 bytes of entropy you are in the danger zone for sure. Note that 1 bit of entropy does not always mean 1 bit in a byte. A byte array of size 8 may have 64 bits of entropy or less.

h) that's basically a hash based stream cipher; it's secure, so an attacker has little to no chance (given you don't reuse the seed) but it is a horribly unreliable (see answer d) and slow stream cipher, so please never ever do this - use a Cipher with "AES/CTR/NoPadding" or "AES/GCM/NoPadding" instead

like image 25
Maarten Bodewes Avatar answered Oct 04 '22 20:10

Maarten Bodewes