2012-05-03 10 views
16

हमारे सिस्टम में स्वचालित रूप से स्व-हस्ताक्षरित प्रमाणपत्रों को एक प्रमुख स्टोर में उत्पन्न करने के लिए कुछ कोड है जिसका उपयोग जेटी द्वारा किया जाता है। एक दिया मेजबान के लिए एक महत्वपूर्ण पहले से ही मौजूद है, तो फिर कुछ नहीं होता लेकिन अगर यह मौजूद नहीं है, हम एक नई कुंजी बना, इस तरह:यदि जेटी की प्रमुख दुकान में एक से अधिक प्रमाणपत्र हैं, तो यह कैसे चुनता है?

public void generateKey(String commonName) { 
    X500Name x500Name = new X500Name("CN=" + commonName); 
    CertAndKeyGen keyPair = new CertAndKeyGen("DSA", "SHA1withDSA"); 
    keyPair.generate(1024); 
    PrivateKey privateKey = keyPair.getPrivateKey(); 
    X509Certificate certificate = keyPair.getSelfCertificate(x500Name, 20*365*24*60*60); 
    Certificate[] chain = { certificate }; 
    keyStore.setEntry(commonName, privateKey, "secret".toCharArray(), chain); 
} 

यह सब जब तक ठीक काम करता है के रूप में वहाँ केवल एक ही कुंजी और प्रमाणपत्र है कुंजी स्टोर में। एक बार जब आप एक से अधिक कुंजी है, अजीब बातें होती हैं जब आप कनेक्ट करने का प्रयास:

java.io.IOException: HTTPS hostname wrong: should be <127.0.0.1> 

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

उदाहरण के लिए:

  • "सीएन = स्थानीय होस्ट" और "सीएन = cheese.mydomain" कुंजी संग्रह में हैं, तो यह हमेशा चुना "सीएन = cheese.mydomain"।
  • यदि "सीएन = 127.0.0.1" और "सीएन = चीज़.मेडोमेन" कुंजी स्टोर में हैं, तो यह हमेशा "सीएन = चीज़.मेडोमेन" चुना जाता है।
  • यदि "सीएन = 1 9 2.168.222.100" (चीज़.मेडोमेन) और "सीएन = चीज़.मेडोमेन" कुंजी स्टोर में हैं, तो यह हमेशा "सीएन = 1 9 2.168.222.100" चुना जाता है।

मैंने कुछ कोड लिखा जो स्टोर में प्रमाण पत्रों के माध्यम से उन्हें प्रिंट करने के लिए लूप करता है और पाया जाता है कि यह लगातार पहले प्रमाणपत्र या उस तरह की छोटी सी चुनौती नहीं चुन रहा है।

तो यह वास्तव में किस मापदंड का उपयोग करता है? शुरू में मैंने सोचा था कि लोकहोस्ट विशेष था लेकिन फिर तीसरा उदाहरण मुझे पूरी तरह से परेशान कर रहा था।

मुझे लगता है कि यह किसी भी तरह से KeyManagerFactory द्वारा तय किया गया है, जो मेरे मामले में SunX509 है।

उत्तर

13

यह वास्तव में KeyManager (आमतौर पर KeyManagerFactory से प्राप्त) द्वारा तय किया जाता है।

एक कीस्टोर में विभिन्न उपनामों के तहत संग्रहीत कई प्रमाणपत्र हो सकते हैं। यदि कोई उपनाम certAlias in the Jetty configuration के माध्यम से स्पष्ट रूप से कॉन्फ़िगर नहीं किया गया है, तो SunX509 कार्यान्वयन उन पहले उपनामों को चुन देगा जिनके लिए एक निजी कुंजी है और चयनित सिफर सूट (आमतौर पर आरएसए, लेकिन शायद आपके मामले में डीएसए) के लिए सही प्रकार की कुंजी है। । यदि आप Sun provider implementation देखते हैं, तो आपको पसंद तर्क के लिए थोड़ा और कुछ है, लेकिन आपको वास्तव में सामान्य रूप से ऑर्डर पर भरोसा नहीं करना चाहिए, केवल उपनाम नाम।

आप निश्चित रूप से अपने SSLContext को अपने स्वयं के X509KeyManager के साथ उपनाम चुनने के लिए दे सकते हैं। आप सभी निर्णय करने के लिए मिलता है socket ही है

chooseServerAlias(String keyType, Principal[] issuers, Socket socket) 
keyType और issuers से

दुर्भाग्य से, के अलावा,: आप को लागू करने के लिए होगा। सबसे अच्छा, आपके द्वारा प्राप्त उपयोगी जानकारी स्थानीय आईपी पता और रिमोट एक है।

जब तक आपका सर्वर एक ही बंदरगाह पर एकाधिक आईपी पते नहीं सुनता है, तो आपको हमेशा एक ही स्थानीय आईपी पता मिल जाएगा।(यहां, जाहिर है, आपके पास कम से कम दो: 127.0.0.1 और 192.168.222.100 है, लेकिन मुझे संदेह है कि आप अपने स्वयं के परीक्षणों को छोड़कर स्थानीयहोस्ट में वास्तव में रूचि नहीं रखते हैं।) सर्वर सर्वर पर सर्वर नाम संकेत (एसएनआई) समर्थन की आवश्यकता होगी अनुरोध किए गए होस्ट नामों के आधार पर निर्णय लेने के लिए (इसे समर्थन करने वाले ग्राहकों द्वारा)। दुर्भाग्यवश, SNI was only introduced in Java 7, but only on the client side

एक और समस्या जिसका आप सामना करेंगे, वह है Java clients will complain about IP addresses in the Subject DN's CN। कुछ ब्राउज़र इसे सहन करेंगे, लेकिन यह HTTPS विनिर्देश (आरएफसी 2818) के अनुरूप नहीं है। आईपी ​​पते आईपी-एड्रेस प्रकार के विषय वैकल्पिक नाम प्रविष्टियां होना चाहिए।

+0

हाँ, हमने आईपी पते के साथ भी चीज़ की खोज की, जिसके परिणामस्वरूप यह देखने के लिए कि क्या वह मैच और रिटर्न सही है, हमारे स्वयं के होस्टनाम सत्यापनकर्ता को लिखना पड़ा। मूल रूप से हमारे पास एक होस्टनाम वेरिफायर था जो हमेशा सत्य लौटा, जिसे स्पष्ट कारणों से बाहर निकालना पड़ा। कई मौजूदा उपयोगकर्ताओं ने अपने "होस्टनाम" के रूप में एक आईपी पता कॉन्फ़िगर किया है और हम अभी तक आक्रामक रूप से हमला नहीं करना चाहते हैं। – Trejkaz

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