Reading ECPrivateKey from JKS KeyStore

I am trying to read an ECPrivateKey (including a certificate chain) from the JKS KeyStore, as shown in the code below.

 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()); 

The curve I use is not supported by the Sun / Oracle security provider, so I use Bouncy Castle. BC is inserted at position 0 on my list of security providers. Storage works fine, reading fails:

 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) 

Apparently, the JKS KeyStore implementation does not go through the list of security providers. However, this works great for other types of KeyStore supported by BC: PKCS12 and BKS . Is there a way to use JKS as a KeyStore type when using BC to restore a key?

The createX509Certificate method used in the above code is defined:

 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; } 
+4
source share
1 answer

My only thought was to implement my own Provider , which could either have a KeyFactory proxy request for the BouncyCastle provider, another that knows about the JKS or proxy all the BouncyCastle requests except for the KeyStore request. Here is the documentation on how to implement a provider.

+2
source

All Articles