// In this case it is initialized using our own seed implementation
// and afterwards (in the thread) using the regular algorithm.
Runnable runnable = new Runnable() {
public void run() {
try {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] seed = sr.generateSeed(20);
synchronized (cachedSecureRandom) {
cachedSecureRandom.setSeed(seed);
seeded = true;
}
} catch (Exception e) {
// NoSuchAlgorithmException
warn("SecureRandom", e);
}
}
};
try {
Thread t = new Thread(runnable);
// let the process terminate even if generating the seed is really slow
t.setDaemon(true);
t.start();
Thread.yield();
try {
// normally, generateSeed takes less than 200 ms
t.join(400);
} catch (InterruptedException e) {
warn("InterruptedException", e);
}
if (!seeded) {
byte[] seed = generateAlternativeSeed();
// this never reduces randomness
synchronized (cachedSecureRandom) {
cachedSecureRandom.setSeed(seed);
}
}
} catch (SecurityException e) {
// workaround for the Google App Engine: don't use a thread
runnable.run();
generateAlternativeSeed();
}
} catch (Exception e) {
// NoSuchAlgorithmException
warn("SecureRandom", e);
cachedSecureRandom = new SecureRandom();
}
return cachedSecureRandom;
}