-
Bug
-
Resolution: Fixed
-
P5
-
6
-
None
-
beta
-
generic
-
generic
from the java-security alias:
Subject: JAVASEC - Comment about SecureRandom seeding
Sender: ###@###.###
Date: 5/18/05
I have a comment about the seeding of a SecureRandom object.
Jean-Francois Raymond was the person that pointed out the underlying
observation to me.
I think that in the setSeed methods, you should add a warning about
seeding a SecureRandom object that has been created.
Indeed, if you call the constructor SecureRandom(), or get an object by
calling the getInstance method, the object is not seeded (with an internal
seed). You have to call nextBytes in order to have the object internally
seeded. The documentation associated to the constructor mentions this,
but not clearly enough in my opinion:
SecureRandom()
Note that this instance of SecureRandom has not been seeded. A call to the
setSeed method will seed the SecureRandom object. If a call is not made
to setSeed, the first call to the nextBytes method will force the
SecureRandom object to seed itself.
It's not explicitly clear that if you immediately call setSeed after
creating the object, that the object will only be seeded with the user
provided seed, and not the internal seed.
The confusion is also enhanced with the documentation of the setSeed method:
setSeed(byte[] seed)
Reseeds this random object. The given seed supplements, rather than
replaces, the existing seed. Thus, repeated calls are guaranteed never to
reduce randomness
Now, if you look at this documentation, it is true that it never says that
your object will be seeded internally if you do
SecureRandom objRand = new SecureRandom();
objRand.setSeed(31415);
But, if you think that 31415 will be mixed-in with the internal seed with
the above code (which is not the case), the documentation doesn't clearly
tell you that that is not the case.
The above code is dangerous, because you can think that it's o.k. to pass
anything you want (any constant for example) to the setSeed method because
it will simply mix-in what you pass with the internal seed, but that is
not the case, the above code is not secure.
To be secure, you have to either not call the setSeed method, or call it
but only after calling nextBytes (and probably just throwing away those
bytes) which will force an internal seeding. The other option is to call
setSeed but making sure you really have a cryptographically random seed.
Furthermore, jdk 1.1.X did not work the same way. With jdk 1.1.X, when
you call the constructor with no argument, the object would seed itself
internally. See for example:
http://www.redbrick.dcu.ie/help/reference/JDK.1.1.8-docs/api/java.security.SecureRandom.html#_top_
This changed with jdk 1.2 and over.
That means, that the code I gave as an example was perfectly secure with
JDK 1.1.X, but not at all secure with jdk 1.2 and above.
Regards,
--Anton
###@###.### 2005-05-18 21:31:25 GMT
Subject: JAVASEC - Comment about SecureRandom seeding
Sender: ###@###.###
Date: 5/18/05
I have a comment about the seeding of a SecureRandom object.
Jean-Francois Raymond was the person that pointed out the underlying
observation to me.
I think that in the setSeed methods, you should add a warning about
seeding a SecureRandom object that has been created.
Indeed, if you call the constructor SecureRandom(), or get an object by
calling the getInstance method, the object is not seeded (with an internal
seed). You have to call nextBytes in order to have the object internally
seeded. The documentation associated to the constructor mentions this,
but not clearly enough in my opinion:
SecureRandom()
Note that this instance of SecureRandom has not been seeded. A call to the
setSeed method will seed the SecureRandom object. If a call is not made
to setSeed, the first call to the nextBytes method will force the
SecureRandom object to seed itself.
It's not explicitly clear that if you immediately call setSeed after
creating the object, that the object will only be seeded with the user
provided seed, and not the internal seed.
The confusion is also enhanced with the documentation of the setSeed method:
setSeed(byte[] seed)
Reseeds this random object. The given seed supplements, rather than
replaces, the existing seed. Thus, repeated calls are guaranteed never to
reduce randomness
Now, if you look at this documentation, it is true that it never says that
your object will be seeded internally if you do
SecureRandom objRand = new SecureRandom();
objRand.setSeed(31415);
But, if you think that 31415 will be mixed-in with the internal seed with
the above code (which is not the case), the documentation doesn't clearly
tell you that that is not the case.
The above code is dangerous, because you can think that it's o.k. to pass
anything you want (any constant for example) to the setSeed method because
it will simply mix-in what you pass with the internal seed, but that is
not the case, the above code is not secure.
To be secure, you have to either not call the setSeed method, or call it
but only after calling nextBytes (and probably just throwing away those
bytes) which will force an internal seeding. The other option is to call
setSeed but making sure you really have a cryptographically random seed.
Furthermore, jdk 1.1.X did not work the same way. With jdk 1.1.X, when
you call the constructor with no argument, the object would seed itself
internally. See for example:
http://www.redbrick.dcu.ie/help/reference/JDK.1.1.8-docs/api/java.security.SecureRandom.html#_top_
This changed with jdk 1.2 and over.
That means, that the code I gave as an example was perfectly secure with
JDK 1.1.X, but not at all secure with jdk 1.2 and above.
Regards,
--Anton
###@###.### 2005-05-18 21:31:25 GMT