我正在编写一个程序(在 Java 中使用 Bouncy Castle API),该程序使用 AES-256/GCM 使用由 ONE EC 密钥对生成的密钥来加密文件。我的对称加密部分工作得很好,但现在证明密钥生成很困难。当尝试在 javax.crypto.KeyAgreement.init() 方法中使用 ECPublicKey 对象时,它返回此错误:
Exception in thread "main" java.security.InvalidKeyException: ECDH key agreement requires ECPrivateKey for initialisation
at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyAgreementSpi.initFromKey(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyAgreementSpi.engineInit(Unknown Source)
at javax.crypto.KeyAgreement.init(KeyAgreement.java:461)
at javax.crypto.KeyAgreement.init(KeyAgreement.java:435)
at Encrpytion.generateKey(Encrpytion.java:188) ---aKA.init(key);---
at Encrpytion.main(Encrpytion.java:40) ---byte[] key = generateKey();---
该方法的源代码如下:
public static byte[] generateKey() {
KeyStore ks = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream("file.pfx");
Scanner input = new Scanner(System.in);
char[] chars = {};
System.out.println("Enter the password for your .pfx: ");
chars = input.nextLine().toCharArray();
input.close();
Enumeration aliasEnum = null;
ks.load(fis, chars);
aliasEnum = ks.aliases();
Key key = null;
Certificate cert = null;
while (aliasEnum.hasMoreElements()){
String param = (String)aliasEnum.nextElement();
if (ks.isKeyEntry(param)) {
String keyName = param;
key = ks.getKey(keyName,chars);
}
cert = ks.getCertificateChain(param)[0];
}
KeyPair kp = new KeyPair(cert.getPublicKey(),(ECPrivateKey) key);
KeyAgreement aKA = null;
aKA = KeyAgreement.getInstance("ECDH", "BC");
aKA.init(key);
aKA.doPhase(kp.getPublic(), true);
return aKA.generateSecret();
}
如何访问证书的 PrivateKey?
**更新:**更新源代码
** 编辑 ** 以下命令和说明可用于创建一些测试文件来演示问题。
#Make root key
openssl ecparam -name secp521r1 -genkey -out root.key
#password protect key
openssl ec -in root.key -out root.key -aes256
####change req x509_attributes to rootCA
#selfsign root
openssl req -new -x509 -key root.key -out root.crt -days 1825 -config openssl.cfg
###comment out req x509_attributes
#make new key for clientCA
openssl ecparam -name secp521r1 -genkey -out client.key
#make clientCA csr
openssl req -new -sha384 -key client.key -out client.csr -config openssl.cfg
#sign clientCA
openssl ca -out client.crt -name root -in client.csr -config openssl.cfg
#make client key
openssl ecparam -name secp521r1 -genkey -out client.key
#make server csr
openssl req -new -sha384 -key client.key -out client.csr -config openssl.cfg
#sign server cert
openssl ca -out client.crt -name client -in client.csr -config openssl.cfg
#MAKE CHAIN - copy base64 encoded root and intermidiate client ca into same "chain.cer" #export user cert
openssl pkcs12 -export -chain -CAfile chain.crt -in client.crt -inkey client.key -out client.pfx -aes256