2012-11-03 3 views
20

다음 코드 : certChain 최종 인증서 발급자 인증서 (즉, 두 개의 인증서)를 보유하고저장 인증서 체인

//used Bouncy Castle provider for keyStore 
keyStore.setKeyEntry(alias, (Key)keyPair.getPrivate(), pwd, certChain); 


이의 일환으로 발급자 인증서를 저장하지 않습니다 키 스토어가 PKCS12의 인스턴스 인 경우 파일 시스템 키 스토어 파일에 저장됩니다.

키 저장소 유형이 PKCS12-3DES-3DES 인 경우 두 인증서를 모두 저장합니다. 이유가 무엇인가요? PKCS12가 두 인증서를 모두 체인의 일부로 간주하지 않습니까?

편집 : 여기에 SSCCE이 있습니다. "JKS"과 함께 제대로 작동하고 "PKCS12"으로 실패합니다. getCertificateChain(String)을 통해 체인의 첫 번째 인증서에만 액세스 할 수 있습니다. 저장된 파일은 두 인증서가 표시된 openssl pkcs12으로 열 수 있습니다.

public void testKeyStore() { 
    try { 
     KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 
     keyPairGenerator.initialize(1024); 
     KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
     PublicKey publicKey = keyPair.getPublic(); 
     PrivateKey privateKey = keyPair.getPrivate(); 
     Certificate[] outChain = { createCertificate("CN=CA", publicKey, privateKey), createCertificate("CN=Client", publicKey, privateKey) }; 

     KeyStore outStore = KeyStore.getInstance("PKCS12"); 
     outStore.load(null, "secret".toCharArray()); 
     outStore.setKeyEntry("mykey", privateKey, "secret".toCharArray(), outChain);    
     OutputStream outputStream = new FileOutputStream("c:/outstore.pkcs12"); 
     outStore.store(outputStream, "secret".toCharArray()); 
     outputStream.flush(); 
     outputStream.close(); 

     KeyStore inStore = KeyStore.getInstance("PKCS12");  
     inStore.load(new FileInputStream("c:/outstore.pkcs12"), "secret".toCharArray()); 
     Key key = outStore.getKey("myKey", "secret".toCharArray()); 
     assertEquals(privateKey, key); 

     Certificate[] inChain = outStore.getCertificateChain("mykey"); 
     assertNotNull(inChain); 
     assertEquals(outChain.length, inChain.length); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     fail(e.getMessage()); 
    } 
} 

private static X509Certificate createCertificate(String dn, PublicKey publicKey, PrivateKey privateKey) throws Exception { 
    X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator(); 
    certGenerator.setSerialNumber(new BigInteger("1")); 
    certGenerator.setIssuerDN(new X509Name(dn)); 
    certGenerator.setSubjectDN(new X509Name(dn)); 
    certGenerator.setNotBefore(Calendar.getInstance().getTime()); 
    certGenerator.setNotAfter(Calendar.getInstance().getTime()); 
    certGenerator.setPublicKey(publicKey); 
    certGenerator.setSignatureAlgorithm("SHA1withRSA"); 
    X509Certificate certificate = (X509Certificate)certGenerator.generate(privateKey, "BC"); 
    return certificate; 
} 
+0

OOI, 무엇입니까? 그렇지 않은 경우 BC 메일 링리스트에 대한 좋은 질문 일 수 있습니다. –

+0

@DuncanJones : BC 메 일링 목록에서이 질문을하고 1 주일 이상 회신을받지 못했습니다. – Cratylus

+0

PKCS # 12는 인증서와 개인 키의 수에 상관없이 아무 것도 가정하지 않습니다. 따라서 PKCS # 12 컨테이너에 구현 될 구현에 따라 달라집니다. –

답변

0

사용하는 JDK에 따라 응용 프로그램을 패키지화하는 다른 방법이 있습니다. Linux와 OpenJDK를 사용하는 곳과 SunJDK (Oracle)를 사용하여 Windows에서 개발하는 곳이 있습니다.

가장 강력한 알고리즘을 사용하려면 마지막으로 추가 구성이 필요합니다. This article은 JCE 정책과 관련된 문제인 경우 도움을 줄 수 있습니다.

+0

이것이 정책상의 문제라고 생각하지 않습니다. OP는 SunJSSE가 아닌 Bouncy Castle을 사용합니다. – martijno

+1

BouncyCastle은 JCE를 구현 한 것으로, 프로젝트에서 BouncyCastle 클래스 만 사용하는 경우에도 제공된 링크로 문제를 해결했습니다. 하지만 당신 말이 맞아요, 제 대답은 크 래틸 러스의 해결책이 될 수도 있고 아닐 수도 있습니다. –

+0

감사합니다. 이것이 도움이된다면 어쨌든 점검 할 것입니다! – martijno

13

귀하의 코드는이 오류가 :

첫째 : 당신은 (클라이언트 인증서가 유효한 체인을 만들기 위해 CA에서 발급해야한다) 인증서 발급자를 설정할 수 없습니다.

두 번째 : 당신은

여기

이 SSCCE 재됩니다 (마지막 CA 클라이언트 ferts해야한다) 인증서 체인을 만들 잘못된 순서를 사용하고 오류없이 작동합니다. 오라클에서 PKCS12 키 저장소 유형 (SunJSSE 프로 바이더)는 같은 증상을 전시

@Test 
public void testKeyStore() throws Exception{ 
     try { 
     String storeName = "/home/grigory/outstore.pkcs12"; 
     KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 
     keyPairGenerator.initialize(1024); 
     KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
     PublicKey publicKey = keyPair.getPublic(); 
     PrivateKey privateKey = keyPair.getPrivate(); 
     Certificate trustCert = createCertificate("CN=CA", "CN=CA", publicKey, privateKey); 
     Certificate[] outChain = { createCertificate("CN=Client", "CN=CA", publicKey, privateKey), trustCert }; 

     KeyStore outStore = KeyStore.getInstance("PKCS12"); 
     outStore.load(null, "secret".toCharArray()); 
     outStore.setKeyEntry("mykey", privateKey, "secret".toCharArray(), outChain); 
     OutputStream outputStream = new FileOutputStream(storeName); 
     outStore.store(outputStream, "secret".toCharArray()); 
     outputStream.flush(); 
     outputStream.close(); 

     KeyStore inStore = KeyStore.getInstance("PKCS12"); 
     inStore.load(new FileInputStream(storeName), "secret".toCharArray()); 
     Key key = outStore.getKey("myKey", "secret".toCharArray()); 
     Assert.assertEquals(privateKey, key); 

     Certificate[] inChain = outStore.getCertificateChain("mykey"); 
     Assert.assertNotNull(inChain); 
     Assert.assertEquals(outChain.length, inChain.length); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     throw new AssertionError(e.getMessage()); 
    } 
    } 
    private static X509Certificate createCertificate(String dn, String issuer, PublicKey publicKey, PrivateKey privateKey) throws Exception { 
     X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator(); 
     certGenerator.setSerialNumber(BigInteger.valueOf(Math.abs(new Random().nextLong()))); 
     certGenerator.setIssuerDN(new X509Name(dn)); 
     certGenerator.setSubjectDN(new X509Name(dn)); 
     certGenerator.setIssuerDN(new X509Name(issuer)); // Set issuer! 
     certGenerator.setNotBefore(Calendar.getInstance().getTime()); 
     certGenerator.setNotAfter(Calendar.getInstance().getTime()); 
     certGenerator.setPublicKey(publicKey); 
     certGenerator.setSignatureAlgorithm("SHA1withRSA"); 
     X509Certificate certificate = (X509Certificate)certGenerator.generate(privateKey, "BC"); 
     return certificate; 
    } 
+0

네, 고쳐 주셨습니다. 잘 했어! 나는 거기에서 유효한 사슬을 생성하지 않고 있다는 것을 깨닫는다. 다른 시험에서 나는 (나는 같은 실패로) 생각 했으므로, 나는 그것이 중요하지 않다고 생각했다. 특히 JKS를 위해서 일했기 때문에. 그것이 주문이라고 밝혀졌습니다! 순서는 다음과 같습니다. endpointtrust anchor last. – martijno

+0

@Cratylus, 이것이 문제를 해결합니까? 이 대답을 수락하기 위해 투표합니다. – martijno

관련 문제