2012-11-03 22 views
20

निम्नलिखित कोड:बचत प्रमाणपत्र श्रृंखला

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

जहां certChain अंत प्रमाण पत्र और प्रमाण पत्र जारीकर्ता (यानी दो प्रमाण पत्र) रखती है,
के हिस्से के रूप जारीकर्ता प्रमाणपत्र सहेजा नहीं करता कुंजीस्टोर PKCS12 का उदाहरण है, तो फ़ाइल सिस्टम कीस्टोर फ़ाइल में सहेजा गया श्रृंखला।

यह दोनों प्रमाणपत्रों को सहेजता है यदि कीस्टोर प्रकार PKCS12-3DES-3DES है। यह क्यों है? क्या पीकेसीएस 12 का मानना ​​है कि दोनों प्रमाण पत्र श्रृंखला का हिस्सा हैं?

संपादित करें: यहां एक 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

ओओआई, क्या ओरेकल (सनजेएसएसई प्रदाता) से पीकेसीएस 12 कीस्टोर प्रकार एक ही लक्षण प्रदर्शित करता है? यदि नहीं, तो यह बीसी मेलिंग सूची के लिए एक अच्छा सवाल हो सकता है। –

+0

@ डंकन जोन्स: मैंने बीसी मेलिंग सूची में यह पूछा और – Cratylus

+0

पर एक उत्तर नहीं मिला PKCS # 12 कुछ भी नहीं मानता क्योंकि यह किसी भी प्रमाणपत्र और उनकी निजी कुंजी के लिए एक कंटेनर है। तो यह कार्यान्वयन-विशिष्ट है जिसे पीकेसीएस # 12 कंटेनर में रखा जाएगा। –

उत्तर

0

आपके द्वारा उपयोग किए जाने वाले जेडीके के आधार पर, आपके आवेदन को पैकेज करने के लिए अलग-अलग तरीके हैं। यह तब होता है जब कुछ लोग जहां लिनक्स और ओपनजेडीके और कुछ अन्य विंडोज़ पर सनजेडीके (ओरेकल) के साथ विकास करते हैं।

सबसे मजबूत एल्गोरिदम का उपयोग करने में सक्षम होने के लिए सबसे अतिरिक्त कॉन्फ़िगरेशन करने के लिए कुछ अतिरिक्त कॉन्फ़िगरेशन है। This article आपकी समस्या आपकी मदद कर सकता है यदि आपकी समस्या जेसीई नीति से संबंधित है।

+0

मुझे नहीं लगता कि यह एक नीति समस्या है। ओपी बाउंसी कैसल का उपयोग करता है, न कि सनजेएसएसई। – martijno

+1

बाउंसीकास्टल जेसीई का कार्यान्वयन है, हमने प्रदत्त लिंक द्वारा हमारी समस्या हल की है, यहां तक ​​कि हम अपने प्रोजेक्ट में केवल बाउंसीकास्टल कक्षाओं का उपयोग कर रहे थे। लेकिन आप सही हैं, मेरा जवाब क्रेटिलस का समाधान हो सकता है या नहीं। –

+0

धन्यवाद। अगर यह मदद करता है तो वैसे भी जांच करेगा! – martijno

13

आपका कोड 2 त्रुटि है:

पहले: आप प्रमाण पत्र के लिए जारीकर्ता सेट नहीं (क्लाइंट प्रमाणपत्र CA द्वारा जारी किया जाना चाहिए वैध श्रृंखला बनाने के लिए)।

दूसरा: तुम गलत आदेश जब प्रमाणपत्र श्रृंखला बनाने का उपयोग करें (ग्राहक ferts, सीए पिछले होना चाहिए)

यहाँ

SSCCE पर फिर से काम कर रहा है, और यह त्रुटियों के बिना काम करता है।

@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

हाँ, आपने इसे ठीक किया है। बहुत बढ़िया! मुझे एहसास है कि मैं वहां एक वैध श्रृंखला नहीं बना रहा था। एक और परीक्षण में मैंने सोचा कि मैं (एक ही विफलता के साथ) था, इसलिए मैंने सोचा कि इससे कोई फर्क नहीं पड़ता, खासकर जब से यह 'जेकेएस' के लिए काम करता था। यह आदेश था कि यह आदेश था! तो आदेश है: endpointtrust एंकर आखिरी। – martijno

+0

@Cratylus, क्या यह आपकी समस्या का समाधान करता है? मैं इस जवाब को स्वीकार करने के लिए वोट देता हूं। – martijno

संबंधित मुद्दे