2012-12-28 2 views
4

아래 코드와 같이 JKS KeyStore에서 ECPrivateKey (인증서 체인 포함)을 다시 읽으려고합니다.JKS KeyStore에서 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 KeyStore 구현은 보안 공급자 목록을 반복하지 않습니다. 그러나 BC : PKCS12BKS에서 지원하는 다른 키 저장소 유형의 경우에는 정상적으로 작동합니다. BC를 사용하여 키를 복구하는 동안 JKS을 KeyStore 유형으로 사용하는 방법이 있습니까?

은 코드에 사용 된 createX509Certificate 방법은 위 주어진다 : 자신의 Provider을 구현하는 것입니다

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; 
} 
+0

첫 번째 위치에 BC를 설치하지 않는 한'keyPairGenerator.initialize (jceParamSpec);을 지나칠 수 없습니다. –

답변

2

내 유일한 생각이 할 수있는 BouncyCastle 공급자에 대한 프록시 "KeyFactory에"요청하고 나머지 하나 "KeyStore"요청을 제외하고 BouncyCastle에 대한 모든 요청을 JKS 또는 프록시에 대해 알고있는 다른 사람. Here's 공급자 구현 방법에 대한 설명서

+0

감사합니다. 어느 쪽이든, 또는 형식대로 PKCS12를 전환하십시오. – martijno