在Windows中,Java SecureRandom.generateSeed失败:意外的CryptoAPI失败 [英] In windows Java SecureRandom.generateSeed failed: Unexpected CryptoAPI failure

查看:322
本文介绍了在Windows中,Java SecureRandom.generateSeed失败:意外的CryptoAPI失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In production environment(Windows 2008 R2, AMD 64, 8 GB RAM), the application sometimes throws the following exception - restart the application solves the problem.

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 :

Took a look at JDK code, find out that the error is because Java_sun_security_provider_NativeSeedGenerator_nativeGenerateSeed returns false :

openjdk-7u2-fcs-src-b13-17_nov_2011 \ jdk \ src \ windows \ native \ sun \ security \ provider \ WinCAPISeedGenerator.c:

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 ,但我不知道为什么会失败以及如何解决.

CryptGenRandom or CryptAcquireContextA returns false, but I don't know why it fails, and how to work around it.

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

Anyone knows why this happens, the work around or how to continue to investigate this problem?

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

Thanks for any advice or reply. Thanks...

顺便说一句-我发现了以下资源-但对解决这个问题不是很有用.

Btw - I found the following resources - but not quite useful to this problem.

http://bugs.sun.com/view_bug.do?bug_id = 6202721

正确使用Java的SecureRandom

在JAVA中确保随机数生成

推荐答案

虽然您的问题闻起来像是并发访问问题,但我为您提供了一种解决方法:将bouncycastle用作JCE提供程序,看看是否可以解决您的问题.将罐子放入您的类路径中,然后在某个时候运行此代码:Security.addProvider(new BouncyCastleProvider());

While your problem smells like a concurrent access problem, I have a workaround for you: Use bouncycastle as a JCE provider and see if that fixes your problem. Put the jar into your classpath, then at some point run this code: Security.addProvider(new BouncyCastleProvider());

这篇关于在Windows中,Java SecureRandom.generateSeed失败:意外的CryptoAPI失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆