加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

在Windows中,Java SecureRandom.generateSeed失败:意外的Crypto

发布时间:2020-12-14 02:22:16 所属栏目:Windows 来源:网络整理
导读:在生产环境( Windows 2008 R2,AMD 64,8 GB RAM)中,应用程序有时会抛出以下异常 – 重新启动应用程序可以解决问题. Caused by: java.lang.InternalError: Unexpected CryptoAPI failure generating seedat sun.security.provider.NativeSeedGenerator.getSeed
在生产环境( 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_2011jdksrcwindowsnativesunsecurityproviderWinCAPISeedGenerator.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,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,randBytes,0);

        CryptReleaseContext(hCryptProv,0);

        return result;
    }

CryptGenRandom或CryptAcquireContextA返回false,但我不知道它为什么会失败,以及如何解决它.

任何人都知道为什么会这样,工作或如何继续调查这个问题?

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

顺便说一句 – 我找到了以下资源 – 但对这个问题并不十分有用.

> https://forums.oracle.com/forums/thread.jspa?threadID=2231037
> http://bugs.sun.com/view_bug.do?bug_id=6202721
> Proper use of Java’s SecureRandom
> Secure Random Number Generation in JAVA

解决方法

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读