2012-09-23 40 views
5

मैं निर्मित क्लास com.sun.net.httpserver.HttpsServer का उपयोग कर जावा (6) में एक कस्टम HTTPS सर्वर बनाने की कोशिश कर रहा हूं। यह तब तक ठीक काम करता है जब तक मुझे क्लाइंट प्रमाणीकरण की आवश्यकता न हो। उस समय यह सर्वर पर एसएसएल डीबग में निम्न अपवाद के साथ विफल रहता है।जावा 6 में बाधा जांच (नेटस्केप प्रमाण प्रकार) को कैसे अक्षम करें?

sun.security.validator.ValidatorException: नेटस्केप प्रमाणपत्र प्रकार SSL क्लाइंट

के लिए उपयोग की अनुमति नहीं देता मैं हमारी आंतरिक सीए द्वारा जारी किए गए प्रमाण पत्र जो सभी आवेदनों हमें आंतरिक के लिए प्रयोग किया जाता है का उपयोग कर रहा हूँ। मैंने प्रमाणपत्र विवरण की जांच की और पाया कि वह प्रकार "एसएसएल सर्वर" था (नीचे उद्धृत विवरण)। चूंकि हमारी नीति सभी आंतरिक अनुप्रयोगों के लिए "एसएसएल सर्वर" प्रकार का उपयोग करना है, इसलिए cerificate को बदलना मुश्किल है। चूंकि मैं क्लाइंट के लिए सर्वर प्रमाण पत्र का उपयोग करना चाहता हूं, मुझे विश्वास नहीं है कि यह एक सुरक्षा समस्या है।

जो मैं खोज रहा हूं वह जावा में इस बाधा जांच को अक्षम करने का एक तरीका है। क्या किसी ने इसका सामना किया है और इसे हल किया है? किसी भी सहायताको बहुत सराहा जाएगा।

शुभकामनाओं सहित, अरुण

Owner: CN=myapp, OU=mygroup, O=mycompany 

Issuer: O=MYCA 

Serial number: 4cc8c1da 

Valid from: Mon Jan 10 13:46:34 EST 2011 until: Thu Jan 10 14:16:34 EST 2013 

Certificate fingerprints: 
     MD5: 8C:84:7F:7A:40:23:F1:B5:81:CD:F9:0C:27:16:69:5E 
     SHA1: 9B:39:0B:2F:61:83:52:93:D5:58:E5:43:13:7A:8F:E1:FD:AC:98:A4 
     Signature algorithm name: SHA1withRSA 
     Version: 3 

Extensions: 

[1]: ObjectId: 2.5.29.16 Criticality=false 
PrivateKeyUsage: [ 
From: Mon Jan 10 13:46:34 EST 2011, To: Wed Jul 11 21:16:34 EDT 2012] 

[2]: ObjectId: 2.5.29.15 Criticality=false 
KeyUsage [ 
    DigitalSignature 
    Key_Encipherment 
] 

[3]: ObjectId: 2.5.29.14 Criticality=false 
SubjectKeyIdentifier [ 
KeyIdentifier [ 
0000: D3 47 35 9B B4 B7 03 18 C6 53 2C B0 FE FD 49 D8 .G5......S,...I. 
0010: D0 FB EE 15          .... 
] 
] 

[4]: ObjectId: 1.2.840.113533.7.65.0 Criticality=false 

[5]: ObjectId: 2.5.29.31 Criticality=false 
CRLDistributionPoints [ 
    [DistributionPoint: 
    [CN=CRL413, O=SWIFT] 
]] 

[6]: ObjectId: 2.5.29.19 Criticality=false 
BasicConstraints:[ 
    CA:false 
    PathLen: undefined 
] 

****[7]: ObjectId: 2.16.840.1.113730.1.1 Criticality=false 
NetscapeCertType [ 
    SSL server 
]**** 

[8]: ObjectId: 2.5.29.35 Criticality=false 
AuthorityKeyIdentifier [ 
KeyIdentifier [ 
0000: 8F AF 56 BC 80 77 A3 FD 9E D2 89 83 98 FE 98 C7 ..V..w.......... 
0010: 20 65 23 CC           e#. 
] 

] 

उत्तर

1

आप डिफ़ॉल्ट विश्वास प्रबंधकों लपेट और इस विशेष अपवाद पकड़ सकते थे।

class IgnoreClientUsageTrustManager extends X509TrustManager { 
    private final X509TrustManager origTrustManager; 
    public class IgnoreClientUsageTrustManager(X509TrustManager origTrustManager) { 
     this.origTrustManager = origTrustManager; 
    } 

    public checkClientTrusted(X509Certificate[] chain, String authType 
     throws IllegalArgumentException, CertificateException { 
     try { 
      this.origTrustManager.checkClientTrusted(chain, authType); 
     } catch (ValidatorException e) { 
      // Check it's that very exception, otherwise, re-throw. 
     } 
    } 

    // delegate the other methods to the origTrustManager 
}   

फिर, उस विश्वास को प्रबंधक का उपयोग एक SSLContext बनाने के लिए और अपने सर्वर के साथ उपयोग करें: यह इन पंक्तियों के साथ कुछ होगा।

TrustManagerFactory tmf = TrustManagerFactory.getInstance(
    TrustManagerFactory.getDefaultAlgorithm()); 
tmf.init((KeyStore)null); 
TrustManager[] trustManagers = tmf.getTrustManagers(); 

for (int i = 0; i < trustManagers.length; i++) { 
    if (trustManagers[i] instanceof X509TrustManager) { 
     trustManagers[i] = IgnoreClientUsageTrustManager(trustManagers[i]); 
    } 
} 

SSLContext sslContext = SSLContext.getInstance("TLS"); 
sslContext.init(... you keymanagers ..., trustManagers, null); 

आपको अपने सर्वर कीस्टोरों (सामान्य के रूप में) से अपने कीमैनर्स को प्रारंभ करना चाहिए। SSLContext सेट करने के लिए आपको HttpsServer के HttpsConfigurator का उपयोग करने में सक्षम होना चाहिए (दस्तावेज़ीकरण में उदाहरण देखें)।

यह तकनीक आदर्श नहीं है, हालांकि। इस कोड को ओरेकल/OpenJDK JRE के लिए विशिष्ट हो जाएगा:

  • सबसे पहले, ValidatorException एक sun.* पैकेज है कि सार्वजनिक एपीआई का हिस्सा नहीं है।
  • दूसरा, यह इस तथ्य पर निर्भर करता है कि अंतिम इकाई की जांच की गई है (जो कुंजी उपयोग एक्सटेंशन को सत्यापित करता है) happens after the rest of the trust validation (जो उस अपवाद को अनदेखा करने के लिए स्वीकार्य बनाता है, क्योंकि आप इस तरह के अन्य मौलिक जांचों को अनदेखा नहीं करते हैं)।

जावा सर्टिफिकेट पथ एपीआई का उपयोग करके, आप इस उद्देश्य के लिए केवल मुख्य उपयोग को अनदेखा कर सकते हैं, इसके बजाय आप अपने स्वयं के सत्यापन को फिर से कार्यान्वित कर सकते हैं। इसके लिए थोड़ा और कोड चाहिए।

अधिक आम तौर पर, आप विनिर्देशों को बाईपास करने का प्रयास कर रहे हैं, अगर आप क्लाइंट प्रमाण पत्र के रूप में एसएसएल/टीएलएस के लिए प्रमाणपत्र का उपयोग करना चाहते हैं, तो उसके पास सही एक्सटेंशन नहीं है। इसके लिए सबसे अच्छा फिक्स आपकी सीए नीति में संशोधन करना है, जो व्यवहार्य होना चाहिए यदि यह एक आंतरिक सीए है। सर्वर प्रमाण पत्रों के लिए टीएलएस क्लाइंट विस्तारित कुंजी उपयोग सेट भी है, यहां तक ​​कि बड़े सीए के साथ भी यह काफी आम है।

+0

आपको बहुत बहुत धन्यवाद। यह बहुत अच्छा काम किया। मैं मानता हूं कि आदर्श समाधान सीए नीति को अपडेट करना है, लेकिन यदि मैं बाईपास समाधान नहीं बनाता, तो मेरे सॉफ़्टवेयर के अपग्रेड को सौ सौ सिस्टम पर अपग्रेड करने के लिए तत्काल प्रमाणपत्र नवीनीकरण की आवश्यकता होगी। – Arun

+2

यह एक गंदे फिक्स की तरह लगता है जो अनंत काल और उसके बाद के लिए चलेगा। – sjas

+0

@ एसजेएस हां, मुझे उम्मीद है कि जो भी इसे पढ़ता है वह पाठ पढ़ता है और कॉपी और पेस्ट नहीं करता है। – Bruno

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

  • कोई संबंधित समस्या नहीं^_^