2012-03-27 55 views
6

Üretim ortamında (Windows 2008 R2, AMD 64, 8 GB RAM), uygulama bazen aşağıdaki kural dışı durumu uygular - uygulamayı yeniden başlattığınızda sorunu çözer.Pencerelerde Java SecureRandom.generateSeed başarısız oldu: Beklenmedik CryptoAPI hatası

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) 

kod sorunu olmaması gerekir:

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

JDK koda göz aldı hata olduğunu öğrenmek çünkü Java_sun_security_provider_NativeSeedGenerator_nativeGenerateSeed döner yanlış:

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 veya CryptAcquireContextA döner yanlış, ama başarısız neden bilmiyorum ve nasıl etrafında çalışmak.

Bunun nedenini bilen, etrafındaki çalışma ya da bu sorunu nasıl araştırmaya devam edeceğini bilen var mı?

Herhangi bir öneri veya yanıt için teşekkürler. Teşekkürler ...

BTW - Ben aşağıdaki kaynakları buldum - ama bu sorun için oldukça yararlı değil.

+1

Cevaplara bakın [burada] (http://stackoverflow.com/questions/8667129/cryptacquirecontexta-fails-in-c-clr-)-Aloaha-kriptografik-sağlayıcı için. Çevrenizdeki yarış koşulları mümkün mü? – Mersenne

cevap

2

Sorununuz eşzamanlı erişimi gibi kokuyor olsa da Sorun, sizin için bir geçici çözümüm var: bouncycastle'ı bir JCE sağlayıcısı olarak kullanın ve sorunun giderilip giderilmediğini görün. Kavanozu sınıf yolunuza koyun, sonra bir noktada şu kodu çalıştırın: Security.addProvider(new BouncyCastleProvider());

+0

Cevabınız için teşekkürler, bunun eşzamanlı erişim ile ilgili bir sorun olduğunu söylediğiniz gibi, kodumuzu optimize ediyoruz: eski kodda, her istek içinSeed üretebiliriz, bu yüzden bu kötü, generateSeed çok fazla kaynak tüketiyor. Yeni kodda, yalnızca bir kez oluşturmayı çağırıyoruz. Bu, müşterinin karşılaştığı problemi çözmüş görünüyor. –

İlgili konular