2012-09-17 21 views
5

मैं एक एम्बेडेड घाट सर्वर और एक ग्राहक के बीच एक क्लाइंट-प्रमाणपत्र प्रमाणीकरण पर काम कर रहा हूँ हस्ताक्षर सत्यापित करें। वे दोनों कीस्टोर का उपयोग करते हैं। ग्राहक प्रमाणपत्र को सर्वर के प्रमाणपत्र द्वारा हस्ताक्षरित किया जाता है जिसे सीए द्वारा हस्ताक्षरित किया जाता है। जेटी क्लाइंट सर्टिफिकेट प्रमाणीकृत करने के लिए 2 विधि का उपयोग करता है, javax.net.ssl.SSLEngine जो काम करता है और वे ऊपर दिए गए कोड का भी उपयोग करते हैं।जावा/KeyStore प्रमाण पत्र

List<X509Certificate> certList = Certificate chain sent by the client 
KeyStore truststore = server's truststore 

//No use of CRL/OSCP/CRLDP 
_crls = null; 
_enableOCSP = false; 
_enableCRLDP = false; 

try{ 
X509CertSelector certSelect = new X509CertSelector(); 
certSelect.setCertificate((X509Certificate) certList.get(0)); 

// Configure certification path builder parameters 
PKIXBuilderParameters pbParams = new PKIXBuilderParameters(truststore, certSelect); 
pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList))); 

// Set maximum certification path length 
pbParams.setMaxPathLength(-1); 

// Enable revocation checking 
pbParams.setRevocationEnabled(true); 

// Set static Certificate Revocation List 
if (_crls != null && !_crls.isEmpty()) 
    pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(_crls))); 

    // Enable On-Line Certificate Status Protocol (OCSP) support 
    if (_enableOCSP) 
     Security.setProperty("ocsp.enable","true"); 

    // Enable Certificate Revocation List Distribution Points (CRLDP) support 
    if (_enableCRLDP) 
     System.setProperty("com.sun.security.enableCRLDP","true"); 

// Build certification path 
CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams);    

// Validate certification path 
CertPathValidator.getInstance("PKIX").validate(buildResult.getCertPath(),pbParams); 
}catch(GeneralSecurityException gse){ 
... 
} 

बेशक मैं इस दूसरी तरह से उपयोग करना चाहिए ... तो चलो इस कोड पर ध्यान केंद्रित करते हैं, यह एक हस्ताक्षरित प्रमाणपत्र सत्यापित करने के लिए एक अच्छा तरीका है? यहाँ मेरी keystores की एक डंप है:

ग्राहक KeyStore:

Entry type: PrivateKeyEntry 
Certificate chain length: 2 
Certificate[1]: 
Owner: [email protected], CN=Servlet, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR 
Issuer: [email protected], CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR 
... 

Certificate[2]: 
Owner: [email protected], CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR 
Issuer: [email protected], CN=Greenpacs Certificate Authority, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR 
... 

सर्वर truststore:

Entry type: trustedCertEntry 

Owner: [email protected], CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR 
Issuer: [email protected], CN=Greenpacs Certificate Authority, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR 

मैं इन keystores के बारे में निश्चित नहीं हूँ, लेकिन मैं अलग से एक के साथ की कोशिश की (जोड़ने क्लाइंट की प्रमाणपत्र श्रृंखला में सीए प्रमाण पत्र, ट्रस्टस्टोर में प्रमाण पत्र जोड़ना) और सत्यापन अभी भी विफल हो गया है। और इन कीस्टोरों के साथ सत्यापन का पहला तरीका (एसएसएलईजीएन) काम करता प्रतीत होता है।

डिबग आउटपुट इसे यहाँ डाल करने के लिए बहुत बड़ी है, लेकिन यहाँ स्टैकट्रेस है: मैं निरसन अक्षम करते हैं

java.security.cert.CertPathValidatorException: Could not determine revocation status 
    at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:153) 
    at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:325) 
    at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:187) 
    at java.security.cert.CertPathValidator.validate(CertPathValidator.java:267) 
    at MainClass.main(MainClass.java:75) 
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:197) 
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255) 
    at sun.security.provider.certpath.CrlRevocationChecker.buildToNewKey(CrlRevocationChecker.java:583) 
    at sun.security.provider.certpath.CrlRevocationChecker.verifyWithSeparateSigningKey(CrlRevocationChecker.java:459) 
    at sun.security.provider.certpath.CrlRevocationChecker.verifyRevocationStatus(CrlRevocationChecker.java:339) 
    at sun.security.provider.certpath.CrlRevocationChecker.verifyRevocationStatus(CrlRevocationChecker.java:248) 
    at sun.security.provider.certpath.CrlRevocationChecker.check(CrlRevocationChecker.java:189) 
    at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:131) 
    ... 4 more 

या अगर मैं कोड काम X509CertSelector के रूप में पिछले प्रमाणपत्र (बजाय पहले की) सेट लेकिन मुझे यकीन नहीं है कि मैं क्या कर रहा हूं।

मैं घाट कोड के बारे में शक करना शुरू कर रहा हूँ, लेकिन मैं प्रमाण पत्र और एसएसएल हेन्डशेकिंग में एक विशेषज्ञ तो यह भी बुरा कुंजीस्टोर/truststore से आ सकता है नहीं कर रहा हूँ। यही कारण है कि मैंने जेटी के बोर्ड पर कोई मुद्दा नहीं बनाया और यह सुनिश्चित करने के लिए कि कोड को बदलने की जरूरत है, पहले यहां पूछा गया था।

इसके अलावा यह पता है कि कैसे जावा में एक हस्ताक्षरित प्रमाणपत्र मान्य करने के लिए उपयोगी हो सकता है।

+0

आप जेएसएसई के माध्यम से ट्रस्ट मैनेजर को यह सब क्यों नहीं करते हैं? – Bruno

+0

क्योंकि मेरा सर्वर गैर प्रमाणपत्र-एथ कनेक्शन भी स्वीकार कर रहा है। मुझे इसे पहले सभी कनेक्शन स्वीकार करना होगा और फिर किसी मामले में ग्राहक के प्रमाण पत्र को मान्य करना होगा। – Ghetolay

+4

नहीं, आपको इच्छित क्लाइंट प्रमाणपत्र विकल्प (आवश्यकता के बजाय) का उपयोग कर क्लाइंट प्रमाणपत्र वैकल्पिक बनाने की आवश्यकता है। – Bruno

उत्तर

0

अपने प्रमाण पत्र सीआरएल की जांच करें या OCSP पहुँचा जा सकता है, तो आप प्रमाण पत्र में इस तरह की जानकारी, जैसे

[1]CRL Distribution Point 
    Distribution Point Name: 
      Full Name: 
       URL=http://crl.verisign.com/pca2-g2.crl 
+0

मैं किसी भी सीआरएल, ओएससीपी या सीआरएलडीपी का उपयोग नहीं करता हूं। मेरे प्रमाण पत्र पर ऐसी कोई लाइन नहीं है। इसके अलावा दिखाया गया कोड पूरा नहीं हुआ है, कुछ "अगर" सीआरएल/ओएससीपी/सीआरएलडीपी के लिए हैं, लेकिन ये "अगर" कभी नहीं पहुंचे हैं क्योंकि मैंने इन विकल्पों को सेट नहीं किया है। क्या मैं ? क्या यह बिल्कुल जरूरी है? – Ghetolay

0

असल में मैं मान्यता अपने आप को क्या करने की जरूरत नहीं है पा सकते हैं।

SSLEngine पहले से ही कर रही है और मान्य प्रमाण पत्र ग्राहक द्वारा भेजा जाता है अगर आप, कोई प्रमाण पत्र या एक अमान्य प्रमाणपत्र ग्राहक getPeerCertificateChain() वापसी अशक्त एक फेंकता द्वारा भेजा जाता है अगर यह getPeerCertificateChain() का उपयोग कर प्राप्त कर सकते हैं अपवाद।

जेट्टी (या किसी भी जावा सर्वलेटकॉन्टर मुझे लगता है) का उपयोग करके आपको क्लाइंट द्वारा वैध प्रमाणपत्र भेजा गया है या नहीं, यह जानने के लिए आपको केवल HttpServletRequest की विशेषता ["javax.servlet.request.X509 प्रमाण पत्र"] की जांच करने की आवश्यकता है।

मैं अभी भी कैसे जावा में एक प्रमाण पत्र को मान्य करने के पता नहीं लेकिन इस समाधान मेरे लिए काफी है :) मैं इसे अपने आप को अब और क्या करने की जरूरत नहीं है। ब्रूनो के लिए धन्यवाद!

+0

getPeerCertificateChain() शून्य वापस नहीं आता है, यह एक अपवाद फेंकता है। – EJP

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