【问题标题】:BouncyCastle Parameter Object Not a ECParameterSpecBouncyCastle 参数对象不是 ECParameterSpec
【发布时间】:2019-02-06 07:08:10
【问题描述】:

我正在使用 EC 使用 bouncycastle 进行加密,

BC 罐子:org.bouncycastle:bcprov-jdk15on:1.59

并使用以下代码初始化KeyPairGenerator

ECNamedCurveParameterSpec parameterSpec
                    = ECNamedCurveTable.getParameterSpec("secp256k1");

System.out.println("Passing ParameterSpec => " + parameterSpec);
System.out.println("Is Instance of org.bouncycastle.jce.spec.ECParameterSpec => " + (parameterSpec instanceof ECParameterSpec));

KeyPairGenerator keyPairGenerator
                    = KeyPairGenerator.getInstance("ECDSA", "BC");
keyPairGenerator.initialize(parameterSpec);

但这给了我以下例外。

java.security.InvalidAlgorithmParameterException: parameter object not a ECParameterSpec
        at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi$EC.initialize(Unknown Source)
        at java.security.KeyPairGenerator.initialize(KeyPairGenerator.java:411)
        at io.gupshup.crypto.web.ECKeyGenerator.generateKeyPair(ECKeyGenerator.java:56)

现在,BouncyCastleProvider 中的代码会检查我在初始化之前已经找到的类的实例。我还打印了该过程中加载的所有类。我无法确定我的代码存在的问题。

作为参考,这是 sout 和类加载器的输出。

[Loaded org.bouncycastle.util.Pack from file:/opt/tomcat0.8/webapps/inbox/WEB-INF/lib/bcprov-jdk15on-1.59.jar]
Passing ParameterSpec => org.bouncycastle.jce.spec.ECNamedCurveParameterSpec@7e5f0eee
Is Instance of org.bouncycastle.jce.spec.ECParameterSpec => true
[Loaded org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi from file:/opt/tomcat0.8/webapps/channel/WEB-INF/lib/bcprov-jdk15on-1.59.jar]
[Loaded org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi$EC from file:/opt/tomcat0.8/webapps/channel/WEB-INF/lib/bcprov-jdk15on-1.59.jar]
[Loaded org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi$ECDSA from file:/opt/tomcat0.8/webapps/channel/WEB-INF/lib/bcprov-jdk15on-1.59.jar]
[Loaded org.bouncycastle.crypto.KeyGenerationParameters from file:/opt/tomcat0.8/webapps/channel/WEB-INF/lib/bcprov-jdk15on-1.59.jar]
[Loaded org.bouncycastle.crypto.params.ECKeyGenerationParameters from file:/opt/tomcat0.8/webapps/channel/WEB-INF/lib/bcprov-jdk15on-1.59.jar]
[Loaded org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator from file:/opt/tomcat0.8/webapps/channel/WEB-INF/lib/bcprov-jdk15on-1.59.jar]
[Loaded org.bouncycastle.crypto.generators.ECKeyPairGenerator from file:/opt/tomcat0.8/webapps/channel/WEB-INF/lib/bcprov-jdk15on-1.59.jar]
[Loaded sun.reflect.GeneratedConstructorAccessor150 from __JVM_DefineClass__]
[Loaded sun.security.jca.JCAUtil from /usr/lib/jvm/jdk1.8.0_131/jre/lib/rt.jar]
[Loaded sun.security.jca.JCAUtil$CachedSecureRandomHolder from /usr/lib/jvm/jdk1.8.0_131/jre/lib/rt.jar]
[Loaded org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec from file:/opt/tomcat0.8/webapps/channel/WEB-INF/lib/bcprov-jdk15on-1.59.jar]
[Loaded java.lang.Throwable$WrappedPrintStream from /usr/lib/jvm/jdk1.8.0_131/jre/lib/rt.jar]

请帮助我解决问题,因为我无法找到问题所在,我已在本地设置中尝试了相同的代码,并且一切正常。

这是 SPI 中的代码,由于某些未知原因而无法正常工作。

if (params == null)
{
    ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
    if (implicitCA == null)
    {
        throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set");
    }

    this.ecParams = null;
    this.param = createKeyGenParamsBC(implicitCA, random);
}
else if (params instanceof ECParameterSpec)
{
    this.ecParams = params;
    this.param = createKeyGenParamsBC((ECParameterSpec)params, random);
}
else if (params instanceof java.security.spec.ECParameterSpec)
{
    this.ecParams = params;
    this.param = createKeyGenParamsJCE((java.security.spec.ECParameterSpec)params, random);
}
else if (params instanceof ECGenParameterSpec)
{
    initializeNamedCurve(((ECGenParameterSpec)params).getName(), random);
}
else if (params instanceof ECNamedCurveGenParameterSpec)
{`initializeNamedCurve(((ECNamedCurveGenParameterSpec)params).getName(), random);`
}
else
{
    throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec");
}

TIA

【问题讨论】:

  • 这可能是一个依赖问题,您的类路径上有 2 个 bouncycastle 版本,并且 parameterspec 类是从另一个 jar 加载的。
  • 只有一个 bouncycastle provider jar
  • EC 用于加密...您有什么具体方案吗?

标签: java security encryption bouncycastle java-security


【解决方案1】:

Bouncy Castle provider 使用 JCA 定义的 API 来进行参数规范。如果您想使用命名曲线 secp256k1,那么您应该使用 JCA 类 ECGenParameterSpec 来指明它:

    Security.addProvider(new BouncyCastleProvider());

    ECGenParameterSpec namedParamSpec = new ECGenParameterSpec("secp256k1");
    KeyPairGenerator ecKPGen = KeyPairGenerator.getInstance("EC", "BC");
    ecKPGen.initialize(namedParamSpec);
    KeyPair ecKP = ecKPGen.generateKeyPair();

当然,如果您需要 Bouncy Castle 是值得商榷的,尽管 Bouncy 中的新 EC 代码表现相当不错。

不管怎样,

    ECGenParameterSpec namedParamSpec = new ECGenParameterSpec("secp256k1");
    KeyPairGenerator ecKPGen = KeyPairGenerator.getInstance("EC");
    ecKPGen.initialize(namedParamSpec);
    KeyPair ecKP = ecKPGen.generateKeyPair();

在我的系统上运行良好。

【讨论】:

  • 它在我的系统中工作......但在服务器中没有......无法确定实际问题。
【解决方案2】:

似乎 java Security.addProvider() 会导致类加载器泄漏。那么就会导致instanceof return false。可以简单的解决如下:

  private static KeyPairGenerator g

  static{
    try {
       cleanEnvAndInitG(CURVE_NAME);
    } catch (NoSuchAlgorithmException e) {
       Random r = new Random();
       //sleep 30ms~300ms
       int time= r.nextInt(300-30+1) + 30;
       Thread.sleep(time);
       cleanEnvAndInitG(CURVE_NAME);
       logger.info(e.getMessage(), e);
    }catch( ...
 }
    public static void cleanEnvAndInitG(String curveName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
        Security.removeProvider(ECDH_PROVIDER);
        Security.addProvider(new BouncyCastleProvider());
        ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curveName);
        keyPairGenerator = KeyPairGenerator.getInstance(ECDH_ALGORITHM, ECDH_PROVIDER);
        keyPairGenerator.initialize(ecSpec, new SecureRandom());
    }

注意:

1)你应该设计初始化失败时的重试机制以避免并发问题。

2) 如果可能,您应该缓存 g 以提高性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 2019-07-27
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多