bcprov-jdk15on-160.jarbctls-jdk15on-160.jar升级到bcprov-jdk15on-161.jarbctls-jdk15on-161.jar或更高版本时遇到问题


  java.lang.InternalError:无法在以下位置打开随机源
  org.bouncycastle.jcajce.provider.drbg.DRBG $ URLSeededSecureRandom $ 1.run(DRBG.java:294)
  在
  org.bouncycastle.jcajce.provider.drbg.DRBG $ URLSeededSecureRandom $ 1.run(DRBG.java:285)
  在java.security.AccessController.doPrivileged(本机方法)在
  org.bouncycastle.jcajce.provider.drbg.DRBG $ URLSeededSecureRandom。(DRBG.java:284)
  在
  org.bouncycastle.jcajce.provider.drbg.DRBG.createCoreSecureRandom(DRBG.java:131)
  在
  org.bouncycastle.jcajce.provider.drbg.DRBG.createInitialEntropySource(DRBG.java:115)
  在org.bouncycastle.jcajce.provider.drbg.DRBG.access $ 400(DRBG.java:29)
  在
  org.bouncycastle.jcajce.provider.drbg.DRBG $ HybridSecureRandom。(DRBG.java:357)
  在
  org.bouncycastle.jcajce.provider.drbg.DRBG.createBaseRandom(DRBG.java:179)
  在org.bouncycastle.jcajce.provider.drbg.DRBG.access $ 100(DRBG.java:29)
  在org.bouncycastle.jcajce.provider.drbg.DRBG $ Default。(DRBG.java:193)
  在sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
  方法)
  sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
  在
  sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
  在java.lang.reflect.Constructor.newInstance(Constructor.java:513)在
  java.lang.Class.newInstance0(Class.java:357)在
  java.lang.Class.newInstance(Class.java:310)在
  java.security.Provider $ Service.newInstance(Provider.java:1221)在
  sun.security.jca.GetInstance.getInstance(GetInstance.java:220)在
  sun.security.jca.GetInstance.getInstance(GetInstance.java:147)在
  java.security.SecureRandom.getInstance(SecureRandom.java:254)在
  java.security.SecureRandom.getDefaultPRNG(SecureRandom.java:176)在
  java.security.SecureRandom。(SecureRandom.java:133)


启用调试日志时。有关\ dev \ urandom的错误


  java.io.FileNotFoundException:\ dev \ urandom(系统找不到
  指定的路径),位于java.io.FileInputStream.open(本机方法),位于
  java.io.FileInputStream。(FileInputStream.java:120)在
  java.io.FileInputStream。(FileInputStream.java:79)在
  sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:70)
  在
  sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:161)
  在java.net.URL.openStream(URL.java:1010)在
  org.bouncycastle.jcajce.provider.drbg.DRBG $ URLSeededSecureRandom $ 1.run(DRBG.java:290)
  在
  org.bouncycastle.jcajce.provider.drbg.DRBG $ URLSeededSecureRandom $ 1.run(DRBG.java:1)
  在java.security.AccessController.doPrivileged(本机方法)在
  org.bouncycastle.jcajce.provider.drbg.DRBG $ URLSeededSecureRandom。(DRBG.java:284)
  在
  org.bouncycastle.jcajce.provider.drbg.DRBG.createCoreSecureRandom(DRBG.java:131)
  在
  org.bouncycastle.jcajce.provider.drbg.DRBG.createInitialEntropySource(DRBG.java:115)
  在org.bouncycastle.jcajce.provider.drbg.DRBG.access $ 2(DRBG.java:77)
  在
  org.bouncycastle.jcajce.provider.drbg.DRBG $ HybridSecureRandom。(DRBG.java:358)
  在
  org.bouncycastle.jcajce.provider.drbg.DRBG.createBaseRandom(DRBG.java:179)
  在org.bouncycastle.jcajce.provider.drbg.DRBG.access $ 0(DRBG.java:162)
  在org.bouncycastle.jcajce.provider.drbg.DRBG $ Default。(DRBG.java:193)


使用160版本时没有问题。

我在Windows 10 64位上使用Java 6 32位。

有人可以帮我吗?

谢谢。

public class BCUpgradeTest {

    public static void main(String[] args) {
        try {
            Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
            Security.insertProviderAt(new BouncyCastleProvider(), 1);
            KeyAgreement ka = KeyAgreement.getInstance("ECDH");
            System.out.println(ka.getProvider().getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

最佳答案

尝试将以下代码添加到程序的启动中:

import java.lang.reflect.Field;
import java.security.Security;
import java.util.Properties;

try {
    Field propsField = Security.class.getDeclaredField("props");
    propsField.setAccessible(true);
    Properties props = (Properties) propsField.get(null);
    props.remove("securerandom.source");
} catch(Exception e) {
    System.err.println("Unable to modify java.lang.Security properties!");
    System.err.println("BouncyCastle DRBG may fail.");
}


至少应该给您不同的错误消息。注意,我还没有实际测试过;它基于以下代码分析。

您发布的FileNotFoundException从使用URLSeededSecureRandomURL构建的file:/dev/random实例中抛出。当然,由于您使用的是Windows,因此/dev/random不存在,并且url.openStream()失败。 (在所有情况下,捕获到的FileNotFoundException都被作为InternalError重新抛出;为什么BouncyCastle使用Error类旨在“指示Java虚拟机中发生了一些意外的内部错误”,我也不知道。 )

但是file:/dev/random部分实际上不是硬编码的。它来自DRBG.createCoreSecureRandom()

private static SecureRandom createCoreSecureRandom()
{
    if (Security.getProperty("securerandom.source") == null)
    {
        return new CoreSecureRandom(findSource());
    }
    else
    {
        try
        {
            String source = Security.getProperty("securerandom.source");

            return new URLSeededSecureRandom(new URL(source));
        }
        catch (Exception e)
        {
            return new SecureRandom();  // we're desperate, it's worth a try.
        }
    }
}


本质上,它调用Security.getProperty("securerandom.source"),如果不是null,则使用该属性构造URLSeededSecureRandom。出于某种原因,即使系统上的securerandom.source是Windows JVM,它在系统上的file:/dev/random也必须类似于securerandom.source,因此BouncyCastle会尝试从中制作CSPRNG。

您需要将null设置为DRBG.createCoreSecureRandom(),以便Security.setProperty("securerandom.source", null)采用其他代码路径。不幸的是,您不能简单地使用Security,因为Properties的属性列表是由ConcurrentHashMap支持的null实例,该实例不允许Security值。而且Properties不允许您访问基础remove()实例,因此您可以在其上调用。因此,您必须使用顶部发布的反射型黑客。

10-02 23:22