Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从JKS密钥库读回ECPrivateKey_Java_Bouncycastle_Keystore_Elliptic Curve - Fatal编程技术网

Java 从JKS密钥库读回ECPrivateKey

Java 从JKS密钥库读回ECPrivateKey,java,bouncycastle,keystore,elliptic-curve,Java,Bouncycastle,Keystore,Elliptic Curve,我正在尝试从JKS密钥库读回ECPrivateKey(包括证书链),如下面的代码所示 String storeType = "JKS", storePass = "secret", storePath = "c:/keystore.ks"; ECNamedCurveParameterSpec bcParamSpec = ECNamedCurveTable.getParameterSpec("brainpoolp224r1"); ECNamedCurveSpec jceParamSpec = ne

我正在尝试从JKS密钥库读回
ECPrivateKey
(包括证书链),如下面的代码所示

String storeType = "JKS", storePass = "secret", storePath = "c:/keystore.ks";
ECNamedCurveParameterSpec bcParamSpec = ECNamedCurveTable.getParameterSpec("brainpoolp224r1");
ECNamedCurveSpec jceParamSpec = new ECNamedCurveSpec(bcParamSpec.getName(), bcParamSpec.getCurve(), bcParamSpec.getG(), bcParamSpec.getN(), bcParamSpec.getH(), bcParamSpec.getSeed());

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
keyPairGenerator.initialize(jceParamSpec);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
ECPublicKey publicKey = (ECPublicKey)keyPair.getPublic();
ECPrivateKey privateKey = (ECPrivateKey)keyPair.getPrivate();

Certificate trustCert =  createX509Certificate("CN=CA", "CN=CA", publicKey, privateKey, "SHA224withECDSA");
Certificate[] chain = { createX509Certificate("CN=Client", "CN=CA", publicKey, privateKey, "SHA224withECDSA"), trustCert };

KeyStore keyStore = KeyStore.getInstance(storeType);
keyStore.load(null, storePass.toCharArray());
keyStore.setKeyEntry("eckey", privateKey, storePass.toCharArray(), chain);

FileOutputStream outputStream = new FileOutputStream(storePath);
keyStore.store(outputStream, storePass.toCharArray());
outputStream.close();

/* Now read it back */
FileInputStream inputStream = new FileInputStream(storePath);
KeyStore keyStore2 = KeyStore.getInstance(storeType);
keyStore2.load(inputStream, storePass.toCharArray());

Key privateKey2 = keyStore2.getKey("eckey", storePass.toCharArray());
Sun/Oracle安全提供商不支持我使用的曲线,因此我使用的是Bouncy Castle。BC插入到我的安全提供程序列表中的位置0。存储工作正常,回读失败:

java.security.UnrecoverableKeyException: Unknown named curve: 1.3.36.3.3.2.8.1.1.5
    at sun.security.provider.KeyProtector.recover(KeyProtector.java:338)
at sun.security.provider.JavaKeyStore.engineGetKey(JavaKeyStore.java:138)
at sun.security.provider.JavaKeyStore$JKS.engineGetKey(JavaKeyStore.java:55)
at java.security.KeyStore.getKey(KeyStore.java:792)
显然,JKS密钥库实现不会在安全提供者列表中循环。但是,对于BC支持的其他密钥库类型,
PKCS12
BKS
,这种方法也很有效。在使用BC恢复密钥时,是否有方法使用
JKS
作为密钥库类型

上述代码中使用的
createX509Certificate
方法如下所示:

private static X509Certificate createX509Certificate(String dn, String issuer, PublicKey publicKey, PrivateKey privateKey, String sigAlg) throws Exception {
    X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
certGenerator.setSerialNumber(BigInteger.valueOf(Math.abs(new Random().nextLong())));
certGenerator.setIssuerDN(new X509Name(issuer));
    certGenerator.setSubjectDN(new X509Name(dn));
    certGenerator.setNotBefore(Calendar.getInstance().getTime());
certGenerator.setNotAfter(Calendar.getInstance().getTime());
certGenerator.setPublicKey(publicKey);
certGenerator.setSignatureAlgorithm(sigAlg);
X509Certificate certificate = (X509Certificate)certGenerator.generate(privateKey, "BC");
return certificate;
}

我唯一的想法是实现您自己的,可以将“KeyFactory”请求代理给BouncyCastle提供程序,其余的代理给另一个了解JKS的提供程序,或者将所有请求代理给BouncyCastle,但“KeyStore”请求除外。关于如何实现提供程序的文档。

我甚至无法通过
keyPairGenerator.initialize(jceParamSpec)除非我在第一个位置安装BC。