在Windows中,Java安全随机生成种子失败:意外的CryptoAPI失败

qoefvg9y  于 2023-01-06  发布在  Windows
关注(0)|答案(2)|浏览(136)

在生产环境(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
打开jdk-7 u2-fcs-src-b13 - 17_nov_2011\jdk\src\windows\本机\sun\安全\提供程序\WinCAPISeed生成器. 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,但我不知道为什么会失败,以及如何解决它。
有人知道为什么会发生这种情况,周围的工作或如何继续调查这个问题吗?
谢谢你的建议或回复。谢谢...
顺便说一句-我找到了下面的资源-但对这个问题不是很有用。

soat7uwm

soat7uwm1#

虽然您的问题看起来像是并发访问问题,但我有一个变通方法:使用bouncycastle作为JCE提供者,看看这是否能解决您的问题。将jar放入您的类路径中,然后在某个时候运行以下代码:第一个月

uqzxnwby

uqzxnwby2#

的确,随机数的生成在CPU周期方面有很高的资源消耗,如果你有可能最小化java.security.SecureRandom.generateSeed方法的调用次数,那就去做吧,肯定会有帮助。
另一方面,请注意,种子生成最终由安全提供程序调用本机函数来实现。
SP的列表位于JAVA_HOME/jre/lib/security/java.security文件中,默认情况下,sun.security.provider.Sun位于顶部,如果这个家伙造成了问题,可以禁用它,以确保索引也被重构。
有关如何从www.example.com文件中禁用安全提供程序的未来参考java.security,请参阅:https://docs.oracle.com/javase/8/docs/technotes/guides/security/p11guide.html#Disable-pkcs11

相关问题