java - 在 Windows Java SecureRandom.generateSeed 中失败 : Unexpected CryptoAPI failure

标签 java windows random

在生产环境(Windows 2008 R2, AMD 64, 8 GB RAM)中,应用程序有时会抛出以下异常 - 重启应用程序即可解决问题。

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

CryptGenRandomCryptAcquireContextA 返回 false,但我不知道它失败的原因以及如何解决它。

任何人都知道为什么会发生这种情况、解决方法或如何继续调查此问题?

感谢您的任何建议或回复。谢谢...

顺便说一句 - 我找到了以下资源 - 但对这个问题不是很有用。

最佳答案

虽然您的问题看起来像是并发访问问题,但我为您提供了一个解决方法:使用 bouncycaSTLe 作为 JCE 提供程序,看看是否能解决您的问题。将 jar 放入您的类路径,然后在某个时候运行此代码:Security.addProvider(new BouncyCaSTLeProvider());

关于java - 在 Windows Java SecureRandom.generateSeed 中失败 : Unexpected CryptoAPI failure,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9885380/

相关文章:

java - 对同一端点的并行请求被阻止

java - 如何在列表中使用 JSON Accumulate 方法?

c# - 以编程方式列出 Windows 10 中所有受支持的语言环境

c++ - 凭据提供程序和命名管道

windows - 如何使用 perfmon 记录 Windows 进程的内存消耗?

java - 转换日期中特定范围的随机数

Python - 随机输出具有结构

java - GridBagLayout:gridwidth > 1 时的对齐方式和宽度

random - 有没有办法生成可公开观察的随机数?

java - JViewport.BACKINGSTORE_SCROLL_MODE 和 setOpaque(false)