Vig*_*ale 4 java encryption cryptography bouncycastle elliptic-curve
我正在尝试使用 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());
Run Code Online (Sandbox Code Playgroud)
我也尝试将公钥转换为 X509EncodedSpec 但我得到了同样的异常
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyPair.getPublic().getEncoded());
KeyFactory factory = KeyFactory.getInstance("ECDH");
PublicKey publicKey = factory.generatePublic(spec);
Run Code Online (Sandbox Code Playgroud)
我得到的例外是
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)
Run Code Online (Sandbox Code Playgroud)
编辑
根据评论,我使用的 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;
Run Code Online (Sandbox Code Playgroud)
请尝试以下操作:
// 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());
Run Code Online (Sandbox Code Playgroud)
请注意,一般来说,当尝试通过 JCE 使用 Bouncy 时,最好保留 JCE 类而不是 Bouncy Castle 类。在这种情况下,问题可能是给密钥生成器的参数。
在上面的代码中,我使用了BouncyCastleProvider.PROVIDER_NAME
但"BC"
当然也同样有效。每次都重新实例化提供者不是一个好主意,尽管它不应该影响最终结果。
确保您有一个最新的系统来运行此代码。此代码在以下系统上进行了测试:
// 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());
Run Code Online (Sandbox Code Playgroud)