【问题标题】:Using BouncyCastle to encrypt with ECIES in Java在 Java 中使用 BouncyCastle 使用 ECIES 进行加密
【发布时间】:2016-01-22 16:35:05
【问题描述】:

我正在尝试使用 Java 中的 BouncyCastle 使用 ECC 算法加密一些内容。但是我得到了 BouncyCastle 库的例外,说不能将JCEECPublicKey 转换为IESKey。我知道KeyPairGenerator生成的公钥是JCEECPublicKey,它不能在javaCipher.init方法中使用。谁能告诉我如何将它转换为公钥或 X509 规范,以便我可以在加密中使用它。

这是我尝试过的代码

// add instance of provider class
Security.addProvider(new BouncyCastleProvider());

// initializing parameter specs secp256r1/prime192v1
ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("prime192v1");

// key pair generator to generate public and private key
KeyPairGenerator generator = KeyPairGenerator.getInstance("ECDH", new BouncyCastleProvider());

// initialize key pair generator
generator.initialize(ecSpec);

// Key pair to store public and private key
KeyPair keyPair = generator.generateKeyPair();

Cipher iesCipher = Cipher.getInstance("ECIES", new BouncyCastleProvider());
iesCipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());

我也尝试将公钥转换为 X509EncodedSpec 但我得到同样的异常

X509EncodedKeySpec spec = new X509EncodedKeySpec(keyPair.getPublic().getEncoded());
KeyFactory factory = KeyFactory.getInstance("ECDH");

PublicKey publicKey = factory.generatePublic(spec);

我得到的例外是

java.lang.ClassCastException: org.bouncycastle.jce.provider.JCEECPublicKey cannot be cast to org.bouncycastle.jce.interfaces.IESKey
    at org.bouncycastle.jce.provider.JCEIESCipher.engineGetKeySize(JCEIESCipher.java:49)
    at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1057)
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1015)
    at javax.crypto.Cipher.init(Cipher.java:1229)
    at javax.crypto.Cipher.init(Cipher.java:1173)
    at com.test.EciesTest.main(EciesTest.java:45)

编辑

根据评论,我使用的 JDK 版本是 JDK 7 - Oracle 我正在使用的导入语句:

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.spec.ECGenParameterSpec;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

【问题讨论】:

  • @ArtjomB。您的意思是在KeyPairGeneratorKeyFactory 中使用ECIES
  • 不显示同样的错误。

标签: java encryption cryptography bouncycastle elliptic-curve


【解决方案1】:

尝试以下方法:

// add instance of provider class
Security.addProvider(new BouncyCastleProvider());

String name = "secp256r1";

// NOTE just "EC" also seems to work here
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME);
kpg.initialize(new ECGenParameterSpec(name));

// Key pair to store public and private key
KeyPair keyPair = kpg.generateKeyPair();

Cipher iesCipher = Cipher.getInstance("ECIES", BouncyCastleProvider.PROVIDER_NAME);
iesCipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());

请注意,在尝试通过 JCE 使用 Bouncy 时,通常最好保留 JCE 类而不是 Bouncy Castle 类。在这种情况下,问题可能是提供给密钥生成器的参数。

在上面的代码中,我使用了BouncyCastleProvider.PROVIDER_NAME,但当然只有"BC" 也能正常工作。每次都重新实例化提供者不是一个好主意,尽管它不应该影响最终结果。


确保您拥有运行此代码的最新系统。此代码已在以下系统上测试:

 --- runtime information --- 
Properties:
    java.vendor                : Oracle Corporation
    java.specification.name    : Java Platform API Specification
    java.specification.version : 1.8
    java.runtime.name          : Java(TM) SE Runtime Environment
    java.runtime.version       : 1.8.0_65-b17
    java.vm.name               : Java HotSpot(TM) 64-Bit Server VM
Unlimited crypto: yes
 --- info for provider Bouncy Castle --- 
Bouncy Castle version: 1.520000
Bouncy Castle provider registered: yes

【讨论】:

  • 我收到以下错误:InvalidAlgorithmParameterException: parameter object not a ECParameterSpeckpg.initialize 位置。我尝试了不同的命名曲线,提供了here,但它们都不起作用。
  • 请列出 Java 运行时、Bouncy Castle 运行时和导入语句。
  • 我已经编辑了我的问题并添加了运行时和导入语句。
  • 很奇怪,你的代码在我的电脑上失败了,在我安装了无限加密(新的 Java 版本更新)后,上面的代码运行良好。我目前正在运行 JDK 1.8 版本 65 和 Bouncy Castle 1.52(已经很旧了)。也许升级到 Java 8 会有所帮助。
  • 不,请安装unlimited crypto files for your Java 8。 ECIES 混合加密。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-22
  • 2013-09-22
  • 1970-01-01
  • 2012-05-22
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多