2012-05-21 16 views
14

मैं त्रुटि के बारे में पिछली पोस्ट को पढ़ता हूं 'डीएच कीपैयर उत्पन्न नहीं कर सका' जब सर्वर 1024 बिट्स से अधिक कुंजी को संत करता है। जेसीई असीमित जार डाउनलोड करने से इस समस्या को ठीक करना चाहिए। परीक्षण वातावरण में, मैंने जावा वेब का उपयोग करते समय उसी वेब सर्वर के लिए निम्नलिखित का सामना किया है, मुझे https क्वेरी करने पर कोई त्रुटि नहीं मिलती है, लेकिन अगर मैं जावा 7 का उपयोग करता हूं तो मुझे 'डीएच कीपैयर उत्पन्न नहीं हो सका' मिलता है।जावा 7 और डीएच कीपैयर उत्पन्न नहीं कर सका

मैंने जेसीई असीमित के लिए जार फ़ाइलों को बदलने की कोशिश की लेकिन फिर भी वही त्रुटि मिलती है। बग 2007 से रिपोर्ट किया गया है, लेकिन यह जावा 6 के लिए क्यों चलता है और जावा 7 के लिए नहीं? क्या फ़ाइलों को उचित नहीं डाउनलोड करने के लिए हैं? मुझे पिछले पोस्ट Java: Why does SSL handshake give 'Could not generate DH keypair' exception? से लिंक मिला है।

इस बिंदु पर मुझे नहीं पता कि क्या करना है। यदि मैं BouncyCastle प्रदाता को लोड करने का प्रयास करता हूं तो मुझे ArrayOutOfIndex अपवाद मिलता है। मेरा सर्वर केवल डीएच एल्गोरिदम की अनुमति देता है, इसलिए मैं उपरोक्त पोस्ट में सुझाए गए एक और एल्गोरिदम का उपयोग नहीं कर सकता।

उत्तर

8

मैं एसएसएलस्कोकेट्स के साथ एक ही मुद्दे पर ठोकर खाई और मुझे लगता है कि मैंने जावा 7 के साथ इस प्रतिगमन के कारण की पहचान की है। कारण क्लाइंट और सर्वर के बीच बातचीत करने वाले सिफरों का कारण है।

SSL_RSA_WITH_RC4_128_MD5 
SSL_RSA_WITH_RC4_128_SHA 
TLS_RSA_WITH_AES_128_CBC_SHA 
TLS_DHE_RSA_WITH_AES_128_CBC_SHA 
TLS_DHE_DSS_WITH_AES_128_CBC_SHA 
SSL_RSA_WITH_3DES_EDE_CBC_SHA 
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA 
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA 
SSL_RSA_WITH_DES_CBC_SHA 
SSL_DHE_RSA_WITH_DES_CBC_SHA 
SSL_DHE_DSS_WITH_DES_CBC_SHA 
SSL_RSA_EXPORT_WITH_RC4_40_MD5 
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA 
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA 
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 
TLS_EMPTY_RENEGOTIATION_INFO_SCSV 

और जावा 7 सक्षम बनाता है इन सिफर:

TLS_DHE_RSA_WITH_AES_128_CBC_SHA 
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA 
SSL_RSA_WITH_RC4_128_SHA 
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 
TLS_ECDHE_RSA_WITH_RC4_128_SHA 
TLS_ECDH_ECDSA_WITH_RC4_128_SHA 
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 
TLS_ECDH_RSA_WITH_RC4_128_SHA 
TLS_EMPTY_RENEGOTIATION_INFO_SCSV 
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 
TLS_RSA_WITH_AES_128_CBC_SHA 
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 
SSL_RSA_WITH_RC4_128_MD5 
TLS_DHE_DSS_WITH_AES_128_CBC_SHA 
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA 
SSL_RSA_WITH_3DES_EDE_CBC_SHA 

सिफर Diffie-Hellman उच्च में आते हैं का उपयोग कर

डिफ़ॉल्ट जावा 6 तक एक TLS कनेक्शन के लिए इन सिफर (प्राथमिकता क्रम में) सक्षम बनाता है जावा 7 पर प्राथमिकता, लेकिन जब तक मजबूत क्रिप्टो पैकेज स्थापित नहीं किया जाता है तब तक वे 1024 बिट्स से अधिक लंबे समय तक कुंजी का समर्थन नहीं करते हैं।

वैकल्पिक हल मैं इस्तेमाल किया सिफर SSLSocket पर जावा 6 से सक्षम निर्दिष्ट करने के लिए किया गया था:

SSLSocketFactory socketFactory = SSLContext.getInstance("TLS").getSocketFactory(); 
SSLSocket socket = (SSLSocket) socketFactory.createSocket(InetAddress.getByName(hostname), port); 
socket.setEnabledCipherSuites(new String[] { 
     "SSL_RSA_WITH_RC4_128_MD5", 
     "SSL_RSA_WITH_RC4_128_SHA", 
     "TLS_RSA_WITH_AES_128_CBC_SHA", 
     "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", 
     "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", 
     "SSL_RSA_WITH_3DES_EDE_CBC_SHA", 
     "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", 
     "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", 
     "SSL_RSA_WITH_DES_CBC_SHA", 
     "SSL_DHE_RSA_WITH_DES_CBC_SHA", 
     "SSL_DHE_DSS_WITH_DES_CBC_SHA", 
     "SSL_RSA_EXPORT_WITH_RC4_40_MD5", 
     "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", 
     "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", 
     "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", 
     "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"}); 

socket.startHandshake(); 
+0

धन्यवाद एक बहुत मैं एक अजीब * java.security.ProviderException का सामना करना पड़ा .security.pkcs11.wrapper.PKCS11Exception: CKR_DOMAIN_PARAMS_INVALID * Webcarab (SSL MITM प्रॉक्सी) का उपयोग करते समय त्रुटि। इन सिफर सुइट्स को स्पष्ट रूप से निर्दिष्ट करने से यह फिर से काम करता है। – Lekensteyn

+1

मैं जावा प्रतिभूतियों में नया हूं। मुझे कोड का यह टुकड़ा कहां लिखना चाहिए? – Shashank

0

आप jdk1.7.0_04 का उपयोग कर रहे हैं, तो jdk1.7.0_21 में अपग्रेड करें। समस्या उस अद्यतन में तय की गई है।

+0

कूल। यह जावा के नए संस्करणों में तय किया गया है। लेकिन मेरा सवाल पुराने संस्करण का उपयोग करने के बारे में है .. जब मैं पुराने संस्करण का उपयोग करता हूं, कभी-कभी यह काम करता है और कभी-कभी यह उपरोक्त अपवाद देता है .. इतना यादृच्छिक व्यवहार क्यों? अगर जावा में यह एक बग है, तो मुझे लगता है कि इसे कभी काम नहीं करना चाहिए? –

+2

दुर्भाग्य से मुझे अभी भी यह त्रुटि '7u21-2.3.9-1ubuntu1' में मिलती है। – expert

+0

मुझे अभी भी यह त्रुटि 1.7.0_45-b18 – duffymo

10

कुछ जोड़ या स्पष्टीकरण:

(Suncle) जावा 7 के बाद से 7u09 डिफ़ॉल्ट रूप से ciphersuites का एक और अधिक समझदार लगातार क्रम का उपयोग करता है, 7u04 में मालूम होता है यादृच्छिक आदेश के विपरीत है। (मेरे पास 04 और 09 के बीच परीक्षण नहीं हैं।) यह आदेश डीएचई से पहले ईसीडीएचई और सादा-आरएसए (उर्फ एकेआरएसए) रखता है, और इस प्रकार यदि समस्या ईसीडीएचई या आरएसए का समर्थन करती है और क्लाइंट वरीयता से सहमत होती है तो समस्या से बचा जाता है। (या ईसीडीएच-फिक्स्ड, लेकिन व्यावहारिक रूप से कोई इसका उपयोग नहीं करता है।) यदि सर्वर डीएचई (किसी भी कारण से) पर जोर देता है और डीएच> 1024 बिट्स का उपयोग करता है, तो आपको अभी भी समस्या है।

यदि पूछताछ (या कोई और) किसी ऐसे सर्वर से कनेक्ट होता है जिसे वास्तव में पूर्णांक-डीएच (और ईसीडीएच या आरएसए नहीं) की आवश्यकता होती है, तो 8 से पहले जावा के साथ काम करने का एकमात्र तरीका सर्वर को डीएच 1024-बिट का उपयोग करना है । कौन सा AFAWK कुछ और वर्षों के लिए तकनीकी रूप से सुरक्षित है, लेकिन पतली मार्जिन के साथ इसे एनआईएसटी जैसे महत्वपूर्ण अधिकारियों द्वारा प्रतिबंधित किया जाता है (csrc.nist.gov पर विशेष पब 800-57 देखें)। (यहां तक ​​कि आरएसए 1024 भी वास्तव में टूटा नहीं गया है, लेकिन शायद यह जल्द ही होगा और इसलिए निषिद्ध है।)

"असीमित ताकत नीति" इस समस्या से प्रासंगिक नहीं है, या कम से कम सीधे नहीं, और अच्छे उत्तर # 6851461 को यह नहीं कहा था। यह सनजेसीई में डीएच पैरामीटर पर प्रतिबंध नहीं बदलता है, जो एक मानक मुद्दे के रूप में माना जाता है (गलत तरीके से) एक ताकत मुद्दा नहीं है। (विशेष रूप से यह उन प्रतिबंधों को लेता है जो डीएसए के लिए सही होते थे, और उन्हें DH पर लागू होते हैं।) यह एईएस -256 और SHA-2 (केवल TLSv1.2) सूट सक्षम करता है, और पर्याप्त अजीब वरीयता सूची देता है, जो शायद चयन परिणाम को डीएचई (विफल) से गैर-डीएचई (कार्य) में बदलें।

आपको जावा 6 सूची में पूरी तरह से वापस जाने की आवश्यकता नहीं है, आपको केवल डीएचई पर अन्य प्रमुख एक्सचेंजों को प्राथमिकता देने की आवश्यकता है, या एक पुनर्विक्रेता सर्वर पूरी तरह से डीएचई ड्रॉप करने की आवश्यकता है। किसी भी निर्यात या सिंगल-डीईएस सूट को सक्षम करने के लिए आपको निश्चित रूप से वापस नहीं जाना चाहिए, जब तक कि विरासत सर्वर के लिए बिल्कुल आवश्यकता न हो; वे अब कई सालों से सुरक्षित नहीं हैं, और डिफ़ॉल्ट रूप से 6 से अधिक लंबे समय तक सक्षम बने रहे हैं।

1

हम जावा 7 और जावा 8 के साथ इस समस्या में भी भाग ले रहे थे। हमने इमानुअल बोर्ग के सुझावों के समान कामकाज का भी उपयोग किया। लेकिन हमारा लक्ष्य सिफरुइट्स की एक निश्चित सूची हार्डकोडिंग से बचाना था। इसलिए हमने उन प्रविष्टियों को हटाने का प्रयास किया जो समस्या का कारण बन गए (परीक्षण और त्रुटि ...)।

String[] enabledCipherSuites = socket.getEnabledCipherSuites(); 

// avoid hardcoding a new list, we just remove the entries 
// which cause the exception 
List<String> asList = new ArrayList(Arrays.asList(enabledCipherSuites)); 

// we identified the following entries causeing the problems 
// "Could not generate DH keypair" 
// and "Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)" 
asList.remove("TLS_DHE_RSA_WITH_AES_128_CBC_SHA"); 
asList.remove("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"); 
asList.remove("TLS_DHE_RSA_WITH_AES_256_CBC_SHA"); 

String[] array = asList.toArray(new String[0]); 
socket.setEnabledCipherSuites(array); 

प्रश्न: क्या कोई इस दृष्टिकोण के साथ कोई समस्या देखता है?

Btw: मामले में आप Apache httpclient उपयोग कर रहे हैं, तो https://issues.apache.org/jira/browse/HTTPCLIENT-1111 दिलचस्प से पता चलता है जो CipherSuites स्थापित करने के लिए कैसे विधि के माध्यम से (httpclient v 4.2 के पश्चात् से शुरू) है

SSLConnectionSocketFactory() {...}.prepareSocket(SSLSocket) 

अद्यतन 2015/10/31 : बेहतर मदद करने के लिए जहां पूरा छद्म कोड उदाहरण है जहाँ आप हुक-इन करने के लिए कैसे prepareSocket ओवरराइड करने के लिए देख() विधि के रूप में इस है, यहाँ का उपयोग करने के संदर्भ को समझना:

HttpClientBuilder builder = HttpClients.custom(); 

SSLContextBuilder sslContextBuilder = SSLContexts.custom(); 
SSLContext sslContext = sslContextBuilder.build(); 

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostNameVerfier) 
{ 


    protected void prepareSocket(SSLSocket socket) throws IOException { 

    // Workaround to use different order of CipherSuites used by Java6 in order 
     // to avoid the the problem of java7 "Could not generate DH keypair" 
     String[] enabledCipherSuites = socket.getEnabledCipherSuites(); 

     // but to avoid hardcoding a new list, we just remove the entries 
     // which cause the exception (via TrialAndError) 
     List<String> asList = new ArrayList(Arrays.asList(enabledCipherSuites)); 

     // we identified the following entries causeing the problems 
     // "Could not generate DH keypair" 
     // and "Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)" 
     asList.remove("TLS_DHE_RSA_WITH_AES_128_CBC_SHA"); 
     asList.remove("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"); 
     asList.remove("TLS_DHE_RSA_WITH_AES_256_CBC_SHA"); 

     String[] array = asList.toArray(new String[0]); 
     socket.setEnabledCipherSuites(array); 

    }; 
}; 

Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslsf).build(); 

PoolingHttpClientConnectionManager conman = new PoolingHttpClientConnectionManager(socketFactoryRegistry); 
builder.setConnectionManager(conman); 

CloseableHttpClient httpClient = builder.build(); 

सावधान रहें हम केवल इस संदर्भ में कोड के इस टुकड़े का उपयोग कर रहे हैं जहां उपयोगकर्ता स्पष्ट रूप से स्वयं हस्ताक्षरित प्रमाणपत्रों (जैसे उदा। परीक्षण पर्यावरण आदि के लिए)। यदि आप ऐसा नहीं करना चाहते हैं, तो एसएसएल-सामान के साथ बेहतर गड़बड़ न करें।

+0

को हल किया गया है, मैं apache httpclient का उपयोग कर रहा हूं, लेकिन यह समझ नहीं सका कि कैसे तैयार है सॉकेट –

6

आप नवीनतम जावा संस्करण का उपयोग कर रहे हैं और अभी भी त्रुटि मिलती है, तो आप java.security में एक सेटिंग बदल सकते हैं (यह देखते हुए जैसे में फ़ोल्डर C: \ Program Files \ जावा \ jre1.8.0_xx \ lib \ सुरक्षा

।! सूरज:
# Example: 
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 
    jdk.tls.disabledAlgorithms=SSLv3, RC4 

विकलांग एल्गोरिथ्म के रूप में DH jdk.tls.disabledAlgorithms में जोड़े

jdk.tls.disabledAlgorithms=SSLv3, RC4, DH 

पुनः प्रारंभ बिल्ला या अपने कार्यक्रम को फिर से चलाएं

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