如何使用EC生成的公钥加密?BouncyCastle中EC密钥加密报错求助
问题:EC密钥非对称加解密算法配置错误导致
InvalidKeyException 测试代码
public void foo(String prov, String keyalgo, String signalgo, String encralgo) throws Exception { // init bouncycastle Security.addProvider(new BouncyCastleProvider()); // generate keypair KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyalgo, prov); if (keyalgo.equals("RSA")) { kpg.initialize(2048); } else if (keyalgo.equals("EC")) { kpg.initialize(new ECGenParameterSpec("brainpoolP384r1")); } KeyPair kp = kpg.generateKeyPair(); // sign Signature s = Signature.getInstance(signalgo, prov); s.initSign(kp.getPrivate()); String data = "heyheyhey"; s.update(data.getBytes()); byte sv[] = s.sign(); // verify s.initVerify(kp.getPublic()); s.update(data.getBytes()); System.out.println("verify: " + s.verify(sv)); // encrypt Cipher c = Cipher.getInstance(encralgo, prov); c.init(Cipher.ENCRYPT_MODE, kp.getPublic()); byte encr[] = c.doFinal(data.getBytes()); // decrypt c.init(Cipher.DECRYPT_MODE, kp.getPrivate()); byte decr[] = c.doFinal(encr); System.out.println("decrypt: " + new String(decr).equals(data)); }
问题场景
- RSA参数调用正常:
foo("BC", "RSA", "SHA256withRSA", "RSA/ECB/OAEPwithSHA1andMGF1Padding"); - EC参数调用失败:
foo("BC", "ECDSA", "SHA256withECDSA", "RSA/ECB/OAEPwithSHA1andMGF1Padding"); - 报错位置:
c.init(Cipher.ENCRYPT_MODE, kp.getPublic()); - 异常信息:
java.security.InvalidKeyException: unknown key type passed to RSA
解决方案
1. 核心问题原因
你给EC密钥传入了RSA专属的加密算法,两者完全不兼容,导致密钥类型验证失败。EC密钥不能直接用RSA加密算法,需要使用EC专门的加密方案——ECIES(椭圆曲线集成加密方案),这是BouncyCastle支持的EC非对称加密标准。
2. 具体修改步骤
(1)修正密钥生成算法
密钥生成时不要用"ECDSA",因为ECDSA是签名算法,密钥生成应该使用通用的"EC":
// 修改调用参数中的keyalgo为"EC" foo("BC", "EC", "SHA256withECDSA", "ECIES");
(2)指定EC兼容的加密算法
将加密算法参数encralgo改为"ECIES",或者更具体的配置(比如指定哈希和对称加密算法):
- 简单默认配置:
"ECIES" - 带具体参数的配置(推荐):
"ECIESwithSHA256andAES-CBC"
(3)可选:自定义ECIES参数
如果需要更精细的控制(比如指定MGF函数、对称加密模式等),可以通过ECIESParameterSpec配置后传入Cipher的init方法:
// 示例:自定义ECIES参数 ECIESParameterSpec params = new ECIESParameterSpec( null, // 共享信息 new SHA256Digest(), new MGF1Digest(new SHA256Digest()), null, // 密钥派生函数参数 new AESEngine(), new CBCBlockCipher(new AESEngine()), new PKCS7Padding() ); c.init(Cipher.ENCRYPT_MODE, kp.getPublic(), params);
3. 修正后的完整调用示例
// 调用EC版本的测试函数 foo("BC", "EC", "SHA256withECDSA", "ECIES");
内容的提问来源于stack exchange,提问作者chris01
相关产品推荐
相关产品推荐

