2012-03-27 14 views
6

In der Produktionsumgebung (Windows 2008 R2, AMD 64, 8 GB RAM) löst die Anwendung manchmal die folgende Ausnahme aus: Starten Sie die Anwendung neu, um das Problem zu beheben.In Windows ist Java SecureRandom.generateSeed fehlgeschlagen: Unerwarteter CryptoAPI-Fehler

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) 

Der Code sollte kein Problem haben:

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); 
    } 

einen Blick auf JDK Code Nahm, herausfinden, dass der Fehler, weil Java_sun_security_provider_NativeSeedGenerator_nativeGenerateSeed kehrt falsch:

openjdk-7u2 -fcs-src-b13-17_nov_2011 \ jdk \ src \ windows \ system \ 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 oder CryptAcquireContextA kehrt falsch, aber ich weiß nicht, warum es nicht, und wie um ihn zu arbeiten.

Wer weiß, warum das passiert, die Arbeit oder wie weiter dieses Problem zu untersuchen?

Danke für jeden Hinweis oder Antwort. Danke ...

BTW - Ich fand die folgenden Ressourcen - aber nicht sehr nützlich für dieses Problem.

+1

Werfen Sie einen Blick auf Antwort [hier] (http://stackoverflow.com/questions/8667129/cryptacquireconttextafails-in-c-clr- For-Aloaha-Kryptographie-Anbieter). Sind Rennbedingungen in Ihrer Umgebung möglich? – Mersenne

Antwort

2

Während Ihr Problem wie ein gleichzeitiger Zugriff riecht Problem, ich habe einen Workaround für Sie: Verwenden Sie Bouncycastle als JCE-Provider und sehen Sie, ob das Ihr Problem behebt. Setzen Sie das Glas in Ihren Klassenpfad, dann führen Sie diesen Code: Security.addProvider(new BouncyCastleProvider());

+0

Vielen Dank für Ihre Antwort, ja, wie Sie sagten, ist dies ein Problem mit gleichzeitiger Zugriff, wir optimieren unseren Code: in alten Code können wir für jede AnfrageSeed erzeugen, das ist schlecht, da GenerateSeed eine Menge Ressourcen verbraucht. Im neuen Code rufen wir nur einmal generateSeed auf. Dies scheint das Problem des Kunden gelöst zu haben. –

Verwandte Themen