For those who are having PERFORMANCE problems with JSSE
I have figured out one of the main causes. If you use the default implementation of the SecureRandom object (you use this if you don't explicitly declare and seed one in your code), the seeding of the object takes an excessive amount of time. The problem is in SeedGenerator, it calls System.currentTimeInMillis() over 10,000 times, along with spawing a new Thread to do this, all in an attempt to seed the SecureRandom.
The work around is too actually create, seed, and use a SecureRandom on your own, not letting the code use it's default methods.
if you call this method:
SSLContext.init(KeyManager [] , TrustManager [] , SecureRandom); and pass nulls in for SecureRandom, you will have the same problem
[example fix]
long l = System.currentTimeMillis() * System.currentTimeMillis(); //this will return a relatively random fully filled 64bits
int i = 64; ///number of bits
byte[] seed = new byte;
while ( --i >= 0 ) {
seed = (byte) l;
l >>= 1; //use each bit of long to seed the byte array
}
new SecureRandom(seed); //use this object
[1154 byte] By [
ctmoore] at [2007-9-26 5:36:14]

I tried the example fix. but I couldn't see any improvement by replacing default SecureRandon with this fix. Here is what I did:
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
long l = System.currentTimeMillis() * System.currentTimeMillis();
int i = 64;
byte[] seed = new byte;
while(--i >= 0)
{
seed = (byte) l;
l >>= 1; // use each bit of long to seed the byte array
}
SecureRandom sr = new SecureRandom(seed);
sr.nextInt();
try
{
com.sun.net.ssl.SSLContext ctx = com.sun.net.ssl.SSLContext.getInstance("TSL");
ctx.init(null, null, sr);
} catch (Exception e)
{
e.printStackTrace();
}
System.setProperty("java.protocol.handler.pkgs",
"com.sun.net.ssl.internal.www.protocol");
//Then open a URL connection using a URL satrt with https
Can you tell me whether I missed anything?
Thanks!
Xufeng
Excuse me, but ...
Don't do this!
The people who implemented the SecureRandom generator did this secure seeding for a purpose. I.e. this is a crucial component of the SecureRandom generator. If you replace it with your code you weaken the whole process.
However, since SecureRandom does this seending only once at the first call of a new instance of SecureRandom you just have to keep this instance.
Regards
Frank
Xufeng_shen,
There is a bug in JSSE 1.0.2's HttpsURLConnection
which tries to create a default SocketFactory
when the class is loaded, and as a result calls the
default SSLContext, which calls new SecureRandom().
If you use Sun's JSSE 1.0.2 https provider,
you'll run into this.
It's been fixed in JSSE in merlin (JDK 1.4), but
not in 1.0.2.
And I agree with FHS1962, don't do this.
You can set a preseed value when doing your
development to cut down on startup time,
but when you go live, remove it.
In order to take advantage of the performance saving, you must use the SecureRandom example written when initializing you SSL context, otherwise the default Provider will instantiate one on its own. Replacing it later will save you nothing.
I was merely trying to document the performance bug in JSSE 1.0.2, which I confirmed through profiling, and apparently fixed in the Merlin 1.4 release. My solution was a temporary work around. In most cases, the seeding I provided would provide a random seed worthy of most, but not all applications. This of course is debatable.
If you are writing for a large scale, commercial production environments, my fix would not be acceptable as the nature of the seed would not be secure enough; the post was only an indication of the type of techniques available to overcome the challenge. Check out an algorithm book from your local library if interested in such work.
I assumed that the code would not be used in commercial development as the default JSSE provider should not be used in commercial development either, one should seek a commercial grade provider as indicated in the JSSE documentation.