当前位置: 首页 > 面试题库 >

使用BouncyCastle在Java中使用ECIES进行加密

南门烈
2023-03-14
问题内容

我正在尝试使用Java中的BouncyCastle使用ECC算法对某些内容进行加密。但是我对BouncyCastle库的说法例外:无法转换JCEECPublicKeyIESKey。我理解的是,所产生的公共密钥KeyPairGeneratorJCEECPublicKey不能在java的使用Cipher.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语句:

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;

问题答案:

请尝试以下操作:

// 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


 类似资料:
  • 我正在尝试编写一个加密文件,它将使用gpg解密,并将以增量方式写入行,而不是在一个块中。我已经在GnuPG中生成了密钥,并且正在使用公钥加密。下面是我正在使用的加密方法: 我有一个小的原型测试类来使用这种方法: 我怎样才能修改这段代码,使它既能加密两行,又能让GnuPG解密它们呢?

  • 我对密码学相当陌生,我正在使用加密密码并将其存储在数据库中。对于加密,我使用算法,并且我想对密码加盐,以防止它对字典攻击。 如有任何帮助,我们将不胜感激。

  • 我希望使用ChaCha加密几个文件,所以我想知道使用是否合适。这个类似乎是为TLS设计的,那么这是否意味着它不是为文件加密设计的呢?内部的方法,例如和似乎可以处理文本而不是二进制文件。 如果是这样的话,有没有人知道如何使用BC的ChaCha实现来进行文件加密?

  • 问题内容: 以下代码对我来说可以用BlowFish加密对字符串加密。 如果我想定义自己的密钥,该怎么做? 问题答案:

  • 问题内容: 我对 密码学还很陌生 ,我正在使用它来 加密 密码并将其存储在数据库中。对于 加密, 我正在使用算法,并且希望对密码加盐以防止再次发生字典攻击。 任何帮助,将不胜感激。 问题答案: 我建议为此使用基于密码的密钥派生函数,而不是基本的哈希函数。像这样:

  • 问题内容: 我使用AES-128 / ecb / PKCS5Padding + base64加密数据时遇到问题。我正在使用以下代码来加密我的数据: 加密后收到,但是无法使用PHP函数在服务器上解密。 当我使用PHP函数加密此数据时: 我收到并且可以使用以下PHP函数成功进行解密: 使用base64加密和解密不会有任何问题。我仅在使用AES-128加密时遇到问题。 问题答案: 问题不在于我最初想到的