В Windows Java SecureRandom.generateSeed не удалось: неожиданный сбой CryptoAPI - PullRequest
6 голосов
/ 27 марта 2012

В производственной среде (Windows 2008 R2, AMD 64, 8 ГБ ОЗУ) приложение иногда выдает следующее исключение - перезапуск приложения решает проблему.

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)

Код не должен иметь проблем:

    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, выясните, что ошибка в том, что Java_sun_security_provider_NativeSeedGenerator_nativeGenerateSeed возвращает 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 или CryptAcquireContextA возвращает false , но я не знаю, почему это терпит неудачу, и как обойти это.

Кто-нибудь знает, почему это происходит, обходной путь или как продолжать исследовать эту проблему?

Спасибо за любой совет или ответ.Спасибо ...

Кстати - я нашел следующие ресурсы - но не совсем полезный для этой проблемы.

1 Ответ

2 голосов
/ 19 июля 2012

Хотя ваша проблема пахнет проблемой одновременного доступа, у меня есть обходной путь: используйте bouncycastle в качестве поставщика JCE и посмотрите, решит ли это вашу проблему. Поместите банку в ваш путь к классу, а затем в какой-то момент запустите этот код: Security.addProvider(new BouncyCastleProvider());

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...