dev@glassfish.java.net

Re: SecureRandom

From: Kumar Jayanti <Vbkumar.Jayanti_at_Sun.COM>
Date: Wed, 02 Sep 2009 18:17:45 +0530

I just tried to collect some info before getting down to defining the
class :

------------------------
 From the SSL FAQ :
Q: It seems the first SSL connection takes longer than subsequent

connections. Is there anything I can do to improve the performance of
the first connection?

A: The SSLContext needs a java.security.SecureRandom object. It is
expensive to seed a SecureRandom object. You should see better
performance for the first connection if you can provide a pre-seeded
SecureRandom
object when initializing the SSLContext. However, extreme care should be
taken in such action as seeding is an important aspect of cryptographic
effectiveness.
------------------------

 From the javadocs of SecureRandom :

public SecureRandom()

    Constructs a secure random number generator (RNG) implementing the
default random number algorithm. The returned SecureRandom object has
not been seeded. To seed the returned object, call the setSeed method.
If setSeed is not called, the first call to nextBytes will force the
SecureRandom object to seed itself. This self-seeding will not occur if
setSeed was previously called.

-----------------------------
 From a Sun forum Thread : http://forums.sun.com/thread.jspa?

forumID=9&threadID=410950

Cipher's, AlgorithmParameters, and SecureRandom objects are not thread
safe. None of the JCE providers use synchronized anywhere. Additonally,
multiple threads using the same cipher at the same time makes little
sense.

Now from what you are talking about where you are using a pool you are
fine so long as your pool is thread safe and that the pool garuntees
that only a single thread will ever be working with a single (crypto)
object at a time. You can reuse a cipher, alg parameter, or secure random
object without fear.

There is one small gotcha on the SecureRandom. SecureRandom uses a seeding
method by default which gives you a certain level of entropy. That entropy
is effective for probably upto 200 or 300 bytes. After that it becomes less
than effective random. So every time it is checked into the pool it should
be reseeded. If you have a /dev/random and you are using a newer version of
java and the JCE then this should not be an issue for you. Just call
generateSeed(N); and then setSeed() when it is checked in.

---------------------------------


SecureRandom :
http://javaboutique.internet.com/resources/books/JavaSec/javasec3_3.html

SecureRandom is easy to use. We can construct one normally, with the
default constructor, and then pass byte arrays to it with nextBytes()
and receive them back filled with random data. For instance, to create
an 8-byte array using secure random we could do the following:

    byte[] randomBytes = new byte[8];
    SecureRandom random = new SecureRandom();
    random.nextBytes(randomBytes);

As an aside, you may have noticed a delay during the running of the
examples we have seen so far and wondered what causes it. Well, it's not
the encryption that's so slow; it's the initialization of
java.security.SecureRandom. Sun's implementation of SecureRandom creates
a great number of threads and checks their interaction over a period of
time. It then uses that to initialize a Pseudo-Random Number Generator
(PRNG). It's the thread creation and interaction that takes so long.

To combat this, a couple of providers have created implementations of
SecureRandom that are at least partially native, giving a huge speed
increase in the seeding of the random number generator. Cryptix
(http://www.cryptix.org) provides an implementation that runs on Linux
and the various BSDs, and Virtual Unlimited
(http://www.virtualunlimited.com) provides one for Windows.

Also, the initialization of SecureRandom is only expensive the first
time it's done in a single Java VM instance. If you have a long-running
program or a server, you can initialize SecureRandom on startup and all
later operations will run quite quickly. You may also want to try to
architect your programs so that they run for a longer period of time
rather than starting and stopping often. This would allow you to
amortize the cost of initialization.

regards,
kumar


Bill Shannon wrote:
> Kumar Jayanti wrote on 08/28/09 02:38:
>> Bill Shannon wrote:
>>> Kedar Mhaswade wrote on 8/27/09 11:28 AM:
>>>
>>>> Bill Shannon wrote:
>>>>
>>>>> Kedar Mhaswade wrote on 8/26/09 5:39 PM:
>>>>>
>>>>>
>>>>>>> Maybe someone should just put an instance of SecureRandom in the
>>>>>>> Habitat
>>>>>>> so everyone can get it by injection and use it?
>>>>>>>
>>>>>> That's doable.
>>>>>>
>>>>> So who should do it?
>>>>>
>>>> I think an appropriate place for this is SecurityService that Kumar
>>>> owns. I also have
>>>> an IdmService that does some identity management related stuff.
>>>> It's an
>>>> Init Service, and I can create the global SecureRandom there. It can
>>>> be the usual Contract/Service thingie. Let me know what you guys
>>>> prefer.
>>>>
>>>
>>> Since I need to use it in the LocalPassword init service, it needs to
>>> be done before then. Is there a way to control order of init services?
>>> Or should it be done by the GlassFish startup code that calls the init
>>> services?
>>>
>>> Kumar, are you the right person to own this?
>>>
>> I will just need to think a little bit and i can send a proposal.
>> Also as i said, i would not put it inside security/core module since
>> it can cause circular dependency issues which we better avoid at this
>> time. I would like to put it in internal-api.
>
> Thanks.
>
>> Should it be a static singleton or a HK2 singleton. If you have an
>> opinion send me your thoughts.
>
> An HK2 singleton seems fine, but I don't have a strong opinion.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>
>