का उपयोग करके मुझे एक कस्टम/स्टैंडअलोन जावा वेबसर्वर लागू करने का कार्य सौंपा गया है जो उसी पोर्ट पर SSL और गैर-SSL संदेशों को संसाधित कर सकता है।एसएसएल हैंडशेकिंग स्व-हस्ताक्षर किए गए कर्ट और एसएसएलईजीएन (जेएसएसई)
मैंने एक एनआईओ सर्वर लागू किया है और यह गैर-एसएसएल अनुरोधों के लिए काफी अच्छा काम कर रहा है। मुझे एसएसएल टुकड़े के साथ एक समय का एक बिल्ली है और वास्तव में कुछ मार्गदर्शन का उपयोग कर सकता है।
यहां मैंने जो किया है, वह यहां है।
एसएसएल और गैर-एसएसएल संदेशों के बीच अंतर करने के लिए, मैं इनबाउंड अनुरोध के पहले बाइट को यह देखने के लिए जांचता हूं कि यह एक एसएसएल/टीएलएस संदेश है या नहीं। उदाहरण:
byte a = read(buf);
if (totalBytesRead==1 && (a>19 && a<25)){
parseTLS(buf);
}
parseTLS में() विधि मैं इस तरह एक SSLEngine का दृष्टांत:
java.security.KeyStore ks = java.security.KeyStore.getInstance("JKS");
java.security.KeyStore ts = java.security.KeyStore.getInstance("JKS");
ks.load(new java.io.FileInputStream(keyStoreFile), passphrase);
ts.load(new java.io.FileInputStream(trustStoreFile), passphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, passphrase);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
SSLContext sslc = SSLContext.getInstance("TLS");
sslc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLEngine serverEngine = sslc.createSSLEngine();
serverEngine.setUseClientMode(false);
serverEngine.setEnableSessionCreation(true);
serverEngine.setWantClientAuth(true);
एक बार SSLEngine instantiated है, मैं सीधे बाहर कोड का उपयोग कर खोलना/रैप तरीकों का उपयोग कर भीतर का डेटा की प्रक्रिया आधिकारिक JSSE Samples की:
log("----");
serverResult = serverEngine.unwrap(inNetData, inAppData);
log("server unwrap: ", serverResult);
runDelegatedTasks(serverResult, serverEngine);
log("----");
serverResult = serverEngine.wrap(outAppData, outNetData);
log("server wrap: ", serverResult);
runDelegatedTasks(serverResult, serverEngine);
हाथ मिलाना के पहले भाग ठीक से काम करने लगता है। ग्राहक एक हाथ मिलाना संदेश भेजता है और सर्वर 4 रिकॉर्ड के साथ एक संदेश के साथ प्रतिक्रिया करता है:
handshake (22)
- server_hello (2)
- certificate (11)
- server_key_exchange (12)
- certificate_request (13)
- server_hello_done (14)
इसके बाद, ग्राहक को तीन भागों के साथ एक संदेश भेजता है:
handshake (22)
- certificate (11)
- client_key_exchange (16)
change_cipher_spec (20)
- client_hello (1)
handshake (22)
*** Encrypted Message ****
SSLEngine ग्राहक के अनुरोध और पार्स करता है unwraps रिकॉर्ड लेकिन रैप विधि ठीक/NEED_UNWRAP की हैंडशेक स्थिति के साथ 0 बाइट उत्पन्न करती है। दूसरे शब्दों में, मेरे पास क्लाइंट को वापस भेजने के लिए कुछ भी नहीं है और हैंडशेक एक डरावना ठहराव के लिए आता है।
यह वह जगह है जहां मैं अटक गया हूं।
डीबगर में, मैं देख सकता हूं कि एसएसएलईएनजीएन, विशेष रूप से सर्वरहैंडशेकर, को कोई सहकर्मी कर्ट नहीं मिला है। यह स्पष्ट है जब मैं क्लाइंट से प्रमाण पत्र रिकॉर्ड देखता हूं जो कि 0 बाइट लंबा है। पर क्यों?
मैं केवल यह मान सकता हूं कि हैलोसेवर प्रतिक्रिया में कुछ गड़बड़ है लेकिन मैं अपनी अंगुली को उस पर नहीं डाल सकता। सर्वर एक मान्य प्रमाण भेज रहा है लेकिन ग्राहक कुछ भी वापस नहीं भेज रहा है। क्या मेरे कीस्टोर में कोई समस्या है? या यह ट्रस्टस्टोर है? या क्या एसएसएलईजीएनआईएन को तुरंत चालू करने के तरीके से कुछ करना है? मैं उलझन में हूं।
युगल अन्य बिंदुओं:
- कुंजीस्टोर और truststore कोड SNIPPIT ऊपर निम्नलिखित ट्यूटोरियल का उपयोग बनाया गया था में संदर्भित: http://www.techbrainwave.com/?p=953
- मैं परीक्षण करने के लिए ग्राहक के रूप में फ़ायरफ़ॉक्स 10 और IE 9 उपयोग कर रहा हूँ सर्वर। दोनों वेब क्लाइंट के लिए वही परिणाम।
- मैं सूर्य/ओरेकल जेडीके 6 और जावा सिक्योर सॉकेट एक्सटेंशन (जेएसएसई) का उपयोग कर रहा हूं जो इसके साथ आता है।
मैं किसी भी मार्गदर्शन आप हो सकता है लेकिन मुझे मत बताओ कृपया मैं पागल हो रहा हूँ या Netty या ग्रिजली या कुछ अन्य मौजूदा समाधान का उपयोग करने के लिए तत्पर हैं। यह इस समय सिर्फ एक विकल्प नहीं है। मैं सिर्फ यह समझना चाहता हूं कि मैं क्या गलत कर रहा हूं।
अग्रिम में धन्यवाद!
बस एक बेवकूफ सवाल: क्या आपने क्लाइंट प्रमाण पत्र जेनरेट और स्थापित किए हैं फ़ायरफ़ॉक्स HTTPS के माध्यम से अपने वेब-सर्वर से कनेक्ट करते समय? – Robert
हां। एफएफ ने मुझे प्रमाण पत्र स्वीकार/अस्वीकार करने के लिए प्रेरित किया। मैंने "तकनीकी जोखिम स्वीकार करते हैं" पर क्लिक किया और मैं उपकरण-> विकल्प-> उन्नत-> एन्क्रिप्शन-> प्रमाणपत्र देखें-> सर्वर के अंतर्गत प्रमाण देख सकता हूं। वास्तव में, एफएफ इसके बिना दूसरा हैंडशेक संदेश नहीं भेजेगा। – Peter
यही वह नहीं है जो मैं पूछ रहा था। मैं ग्राहक प्रमाण पत्र के लिए पूछ रहा था। एसएसएल क्लाइंट प्रमाणीकरण वैकल्पिक है और ज्यादातर कॉर्पोरेट वातावरण में उपयोग किया जाता है, अक्सर चिप-कार्ड के संयोजन में। यदि ग्राहक के पास प्रमाण पत्र स्थापित नहीं है (फ़ायरफ़ॉक्स अनुभाग "आपका प्रमाणपत्र") तो यह एक नहीं भेजेगा। – Robert