In production environment(Windows 2008 R2, AMD 64, 8 GB RAM), the application sometimes throws the following exception - restart the application solves the problem.
Caused by: java.lang.InternalError: Unexpected CryptoAPI failure generating seed
at sun.security.provider.NativeSeedGenerator.getSeedBytes(NativeSeedGenerator.java:43)
at sun.security.provider.SeedGenerator.generateSeed(SeedGenerator.java:117)
at sun.security.provider.SecureRandom.engineGenerateSeed(SecureRandom.java:114)
at java.security.SecureRandom.generateSeed(SecureRandom.java:475)
The code should have no problem :
public void generateToken ()
{
SecureRandom secureRandom = new SecureRandom();
int seedByteCount = 20;
byte[] seed = secureRandom.generateSeed(seedByteCount);
secureRandom.setSeed(seed);
String random = String.valueOf(secureRandom.nextLong());
setToken(random);
}
Took a look at JDK code, find out that the error is because Java_sun_security_provider_NativeSeedGenerator_nativeGenerateSeed
returns false :
openjdk-7u2-fcs-src-b13-17_nov_2011\jdk\src\windows\native\sun\security\provider\WinCAPISeedGenerator.c :
JNIEXPORT jboolean JNICALL Java_sun_security_provider_NativeSeedGenerator_nativeGenerateSeed(JNIEnv *env, jclass clazz, jbyteArray randArray)
{
HCRYPTPROV hCryptProv;
jboolean result = JNI_FALSE;
jsize numBytes;
jbyte* randBytes;
if (CryptAcquireContextA(&hCryptProv, "J2SE", NULL, PROV_RSA_FULL, 0) == FALSE) {
/* If CSP context hasn't been created, create one. */
if (CryptAcquireContextA(&hCryptProv, "J2SE", NULL, PROV_RSA_FULL,
CRYPT_NEWKEYSET) == FALSE) {
return result;
}
}
numBytes = (*env)->GetArrayLength(env, randArray);
randBytes = (*env)->GetByteArrayElements(env, randArray, NULL);
if (CryptGenRandom(hCryptProv, numBytes, randBytes)) {
result = JNI_TRUE;
}
(*env)->ReleaseByteArrayElements(env, randArray, randBytes, 0);
CryptReleaseContext(hCryptProv, 0);
return result;
}
CryptGenRandom
or CryptAcquireContextA
returns false, but I don't know why it fails, and how to work around it.
Anyone knows why this happens, the work around or how to continue to investigate this problem?
Thanks for any advice or reply. Thanks...
Btw - I found the following resources - but not quite useful to this problem.
https://forums.oracle.com/forums/thread.jspa?threadID=2231037
http://bugs.sun.com/view_bug.do?bug_id=6202721
Proper use of Java’s SecureRandom
Secure Random Number Generation in JAVA
While your problem smells like a concurrent access problem, I have a workaround for you: Use bouncycastle as a JCE provider and see if that fixes your problem. Put the jar into your classpath, then at some point run this code: Security.addProvider(new BouncyCastleProvider());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With