2011-08-28 25 views
10

मैं सुरक्षित सॉकेट परत (HTTPS) का उपयोग कर जावा में मेरी एक PHP स्क्रिप्ट के साथ कनेक्शन स्थापित करने का प्रयास कर रहा हूं, लेकिन मुझे पता चला है कि अधिकतम सुरक्षा/वैधता सुनिश्चित करने के लिए मुझे SSL प्रमाणपत्र आयात करना है कि मेरी वेबसाइट मेरे आवेदन में उपयोग करती है ... कुछ मुझे नहीं पता कि कैसे करना है।जावा और एसएसएल प्रमाणपत्र

यदि यह मदद करता है, तो मेरा SSL प्रमाणपत्र स्वयं हस्ताक्षरित नहीं है, बल्कि StartSSL द्वारा प्रदान किया गया है और मैं ग्रहण आईडीई का उपयोग कर रहा हूं।

क्या कोई मुझे सही दिशा में इंगित कर सकता है? यानी मुझे किन फाइलों की आवश्यकता है, मुझे उन्हें कहां आयात करना चाहिए और मुझे जावा में किस कोड की आवश्यकता है?

+0

यदि यह कोई प्रमाण पत्र आयात किए बिना काम करता है, तो मुझे नहीं पता कि सुरक्षा कैसे सुनिश्चित की जाएगी/बढ़ाया जाएगा वेब साइट प्रमाण पत्र आयात करके। यदि कोई प्रमाण पत्र आयात किया जाना चाहिए तो यह StartSSL का मूल प्रमाणपत्र है, लेकिन आपका वेबसाइट प्रमाण पत्र नहीं, क्योंकि जावा स्टार्टएसएसएल को मान्य प्रमाणन प्राधिकरण के रूप में नहीं पहचान सका। –

+0

@ जेबी ओह। ऐसा इसलिए था क्योंकि मेरे पिछले प्रश्न में चबर्ड ने कहा था कि मुझे यह सुनिश्चित करने के लिए अपने क्लाइंट में सर्वर के प्रमाणपत्र को प्रमाणित करना सुनिश्चित करना चाहिए कि मैं झूठी सेवा से बात कर रहा हूं और उसने कीटोल के बारे में कुछ बताया है। तो यदि आपकी कहानियां वेबसाइट प्रमाण पत्र आयात करने से सुरक्षा प्रभावित नहीं होती है, तो कोई भी SSL प्रमाणपत्र क्यों आयात करेगा? – Andy

+1

यह जावा का एसएसएल स्टैक है जो वेब साइट सर्टिफिकेट को मान्य करेगा, जैसे ब्राउजर करता है। क्या आप उन सभी एसएसएल वेबसाइटों का प्रमाण पत्र आयात करते हैं जिन्हें आप उनसे मिलने से पहले देखते हैं? नहीं। ब्राउज़र उनके प्रमाण पत्र को मान्य करता है क्योंकि यह एक प्रसिद्ध प्रमाण पत्र प्राधिकरण द्वारा प्रमाणित है जिसे ब्राउज़र जानता है। StartSSL आपके मामले में प्रमाण पत्र प्राधिकरण है। जावा एक ही काम करता है। आपको StartSSL के प्रमाणपत्र को आयात करने की आवश्यकता हो सकती है, लेकिन वेबसाइट प्रमाण पत्र नहीं। –

उत्तर

24

मुझे लगता है कि पता चला है maxium सुरक्षा/वैधता सुनिश्चित करने के मैं जब आप उस बयान अपने आवेदन में SSL प्रमाणपत्र है कि मेरी वेबसाइट का उपयोग करता है आयात करने के लिए

आप आंशिक रूप से सही हैं। आपको अपना एसएसएल प्रमाणपत्र आयात करने की आवश्यकता नहीं है। यह पर्याप्त है कि StartSSL CA प्रमाणपत्र आयात किया जाए।

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

आपके एप्लिकेशन के अंतिम उपयोगकर्ता जावा रनटाइम के भीतर SSL समर्थन पर भरोसा करेंगे, जो सर्वर-प्रमाणपत्र प्रमाणित होने के बाद, साइट पर एसएसएल कनेक्शन स्थापित करने के लिए एप्लिकेशन को सक्षम करेगा। ट्रस्टस्टोर में सीए प्रमाणपत्रों के डिफ़ॉल्ट सेट के साथ जावा रनटाइम जहाजों, और सफलतापूर्वक स्थापित होने के लिए एसएसएल कनेक्शन के लिए एकमात्र शर्त यह है कि सर्वर के एसएसएल प्रमाणपत्र ट्रस्टस्टोर में सीए में से एक द्वारा जारी किया जाना चाहिए। StartSSL के प्रमाण पत्र कम से कम 6 संस्करण के रूप में, जावा रनटाइम की truststore में मौजूद नहीं हैं, और इसलिए:

  • आप StartSSL CA प्रमाणपत्र आयात करने के अभ्यास को पूरा करने के लिए अपने अंत उपयोगकर्ताओं को निर्देशित कर सकता है जावा ट्रस्टस्टोर में। लिंक जो मदद कर सकते हैं this StartSSL forum thread (ट्रस्टस्टोर में सीए कर्ट आयात करने के लिए केवल पहले 4 चरणों की आवश्यकता है), a GitHub project, और this blog post; एक अस्वीकरण - मैंने उनमें से किसी का उपयोग करने का प्रयास नहीं किया है और आपको इसे अपने जोखिम पर उपयोग करना चाहिए।
  • या, आप -Djavax.net.ssl.trustStore=<path_to_truststore> -Djavax.net.ssl.trustStorePassword=<truststore_password> JVM स्टार्टअप झंडे का उपयोग कर अपनी खुद की truststore के साथ अपने आवेदन को प्रारंभ सकता है, या आरंभ SSL कनेक्शन करने से पहले निम्न कोड निष्पादित करें:

    System.setProperty("javax.net.ssl.trustStore","<path_to_truststore>"); 
    System.setProperty("javax.net.ssl.trustStorePassword","<truststore_password>"); 
    

    यह एक व्यवहार्य दृष्टिकोण ही अगर आपके आवेदन एक है जावा एसई एप्लीकेशन जो एक एप्लेट नहीं होता है (या ट्रस्टस्टोर को निर्दिष्ट करने के तरीके पर समान प्रतिबंध वाले एप्लिकेशन)।


यह भी Java keytool documentation पढ़ें मदद मिलेगी।

+0

आपके सूचनात्मक और 'अंतर्दृष्टिपूर्ण' उत्तर के लिए धन्यवाद! असल में आप जो कह रहे हैं, वह है कि मुझे केवल स्टार्टएसएसएल के सीए प्रमाणपत्र को आयात करने की आवश्यकता है और फिर मुझे सुरक्षित होना चाहिए? यदि मैं सही हूं, तो आपके द्वारा प्रदान किए गए लिंक केवल अंतिम उपयोगकर्ता पर लागू होते हैं और प्रमाणपत्र मेरे सॉफ़्टवेयर के साथ वितरित नहीं किया जाएगा, लेकिन आपके दूसरे बुलेट बिंदु में विधि (ओं) का अर्थ है कि StartSSL का CA प्रमाणपत्र हमेशा वहां रहेगा और मेरे अंतिम उपयोगकर्ता कुछ भी नहीं करना पड़ेगा? क्योंकि मैं वास्तव में नहीं चाहता कि मेरे ग्राहकों को StartSSL के CA प्रमाणपत्र आयात करना होगा ... – Andy

+0

सीए प्रमाणपत्र कई उद्देश्यों को पूरा करता है; टॉमकैट जैसे जावा सर्वर के लिए जो स्टार्टएसएसएल द्वारा जारी किए गए साइट सर्टिफिकेट के साथ एचटीटीपीएस पर एक साइट की सेवा कर सकता है, आपको साइट सर्टिफिकेट के साथ एक कीस्टोर और स्टार्टएसएसएल सीए प्रमाणपत्र के साथ * ट्रस्टस्टोर भी होना चाहिए। एक एसएसएल क्लाइंट, जैसे ब्राउज़र, या आपके जावा एप्लिकेशन के लिए, ट्रस्टस्टोर में स्टार्टएसएसएल सीए प्रमाणपत्र होना चाहिए (या जो भी ट्रस्ट सत्यापित करने के लिए उपयोग किया जाता है)। इसलिए आपके अंतिम उपयोगकर्ताओं को सीए प्रमाणपत्र को कैकर्ट फ़ाइल में आयात करना होगा, और ऐप द्वारा बनाए गए कनेक्शन सुरक्षित होंगे। –

+0

... मुझे नहीं पता कि इससे कोई फर्क पड़ता है लेकिन मैं अपने अनुप्रयोगों के साथ जेआरई वितरित करने के लिए launch4j का उपयोग करने की योजना बना रहा हूं ताकि मुझे अपने ग्राहकों पर भरोसा न करना पड़े। तो, क्या इसका मतलब यह हो सकता है कि स्टार्टएसएसएल का सीए प्रमाणपत्र जेआरई के साथ भी पैक हो जाता है? – Andy

0

निम्नलिखित आलेख पर एक नज़र डालें: http://stilius.net/java/java_ssl.php इसमें कोड उदाहरण शामिल है जो कि यदि आप कोड से अपनी स्क्रिप्ट तक पहुंचने का प्रयास कर रहे हैं तो मदद कर सकते हैं।

ध्यान दें कि आप या तो सिस्टम गुण

javax.net.ssl.keyStore 
javax.net.ssl.keyStorePassword 

का उपयोग करना चाहिए keytool उपकरण का उपयोग करके JVM को SSL प्रमाणपत्र पारित या JRE कुंजीस्टोर में आयात करने

+0

आपके उत्तर @ सर्गी के लिए धन्यवाद। दुर्भाग्यवश, मैंने आपके द्वारा सुझाए गए लेख को पहले से ही देखा था। यह शायद मददगार होगा अगर मैंने थोड़ा सा अध्ययन किया लेकिन यह मेरे लिए एक बिल्कुल नया विषय है और मैं थोड़े समय के दबाव में हूं, इसलिए मुझे यह कहने से नफरत है, लेकिन मैं यहां सबसे आसान तरीका ढूंढ रहा था। सौभाग्य से, मैंने विनीट के साथ चर्चा में मेरे लिए सबसे अच्छा तरीका खोजा है, लेकिन वैसे भी धन्यवाद! – Andy

0

मुझे लगता है कि पता चला है maxium सुनिश्चित करने के लिए सुरक्षा/वैधता मुझे एसएसएल प्रमाणपत्र

आयात नहीं करना है। आपको केवल उस चरण की आवश्यकता है यदि आपके ग्राहक पहले से ही सर्वर प्रमाणपत्र के हस्ताक्षरकर्ता पर भरोसा नहीं करते हैं, जो केवल तब उत्पन्न होता है जब सर्वर प्रमाणपत्र स्वयं हस्ताक्षरित या हस्ताक्षरित हो। एक आंतरिक सीए द्वारा

+0

आपके उत्तर के लिए धन्यवाद। हालांकि, दुर्भाग्यवश मैंने पहले से ही एक प्रमाण पत्र आयात कर लिया है - लेकिन मुझे नहीं लगता कि यह अभी आवश्यक था, लेकिन मुझे कैसे पता चलेगा कि मेरे ग्राहक सर्वर प्रमाण पत्र के हस्ताक्षरकर्ता पर भरोसा नहीं करते हैं: क्या मुझे मेरे द्वारा अपवाद प्राप्त होगा 'Htttpsurlconnection' का उपयोग करते समय आवेदन? – Andy

+0

@ एंडी आपको वही अपवाद मिलेगा जो आपको पहले स्थान पर मिला था। – EJP

1

निम्न विधि डिफ़ॉल्ट (cacerts) कुंजीस्टोर लोड करता है, एक प्रमाण पत्र स्थापित किया गया है, तो देखने के लिए जाँच करता है, और यह नहीं तो स्थापित करता है। यह किसी भी सर्वर पर keystore कमांड मैन्युअल रूप से चलाने की आवश्यकता को समाप्त करता है।

यह मानता है कि डिफ़ॉल्ट कुंजीस्टोर पासवर्ड (changeit) में कोई बदलाव नहीं है, CACERTS_PASSWORD अद्यतन नहीं तो। ध्यान दें कि विधि प्रमाणपत्र जोड़ने के बाद कीस्टोर को सहेजता है, इसलिए एक बार सर्टिफिकेट स्टोर में स्थायी रूप से होने के बाद चलाने के बाद।

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.cert.Certificate; 
import java.security.cert.CertificateException; 
import java.security.cert.CertificateFactory; 

/** 
* Add a certificate to the cacerts keystore if it's not already included 
*/ 
public class SslUtil { 
    private static final String CACERTS_PATH = "/lib/security/cacerts"; 

    // NOTE: DO NOT STORE PASSWORDS IN PLAIN TEXT CODE, LOAD AT RUNTIME FROM A SECURE CONFIG 
    // DEFAULT CACERTS PASSWORD IS PROVIDED HERE AS A QUICK, NOT-FOR-PRODUCTION WORKING EXAMPLE 
    // ALSO, CHANGE THE DEFAULT CACERTS PASSWORD, AS IT IMPLORES YOU TO! 
    private static final String CACERTS_PASSWORD = "changeit"; 

    /** 
    * Add a certificate to the cacerts keystore if it's not already included 
    * 
    * @param alias The alias for the certificate, if added 
    * @param certInputStream The certificate input stream 
    * @throws KeyStoreException 
    * @throws NoSuchAlgorithmException 
    * @throws CertificateException 
    * @throws IOException 
    */ 
    public static void ensureSslCertIsInKeystore(String alias, InputStream certInputStream) 
      throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{ 
     //get default cacerts file 
     final File cacertsFile = new File(System.getProperty("java.home") + CACERTS_PATH); 
     if (!cacertsFile.exists()) { 
      throw new FileNotFoundException(cacertsFile.getAbsolutePath()); 
     } 

     //load cacerts keystore 
     FileInputStream cacertsIs = new FileInputStream(cacertsFile); 
     final KeyStore cacerts = KeyStore.getInstance(KeyStore.getDefaultType()); 
     cacerts.load(cacertsIs, CACERTS_PASSWORD.toCharArray()); 
     cacertsIs.close(); 

     //load certificate from input stream 
     final CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
     final Certificate cert = cf.generateCertificate(certInputStream); 
     certInputStream.close(); 

     //check if cacerts contains the certificate 
     if (cacerts.getCertificateAlias(cert) == null) { 
      //cacerts doesn't contain the certificate, add it 
      cacerts.setCertificateEntry(alias, cert); 
      //write the updated cacerts keystore 
      FileOutputStream cacertsOs = new FileOutputStream(cacertsFile); 
      cacerts.store(cacertsOs, CACERTS_PASSWORD.toCharArray()); 
      cacertsOs.close(); 
     } 
    } 
} 

इतना है कि यह प्रयोग करें:

SslUtil.ensureSslCertIsInKeystore("startssl", new FileInputStream("/path/to/cert.crt")); 
+0

मेरे कोड में यह परिणाम java.io.FileNotFoundException: C: \ Program Files (x86) \ Java \ jre1.8.0_45 \ lib \ security \ cacerts (एक्सेस अस्वीकार है) मैं एक temp फ़ोल्डर में certs डाउनलोड करता हूं, फिर इसे एक अद्वितीय उपनाम (starttls नहीं) और fileInputStream के साथ आयात करें। मेरा प्रमाणपत्र एक HTTPS सर्वर (www.gmx.at) से आता है – lumo

+0

धन्यवाद! इस पोस्ट ने मुझे एक कीस्टोर पढ़ने में मदद की। – rray

+0

प्रश्न, क्या यह आपके कोड में सादे-पाठ के रूप में पासवर्ड स्टोर करने के लिए एक बहुत बड़ा सुरक्षा छेद नहीं है? या इससे कोई फर्क नहीं पड़ता कि एसएसएल कनेक्शन की बात आती है? – Flaom

2

जाहिर है किसी कारण से mailgun इंजीनियरों हमें यह कैसे हल करने के लिए स्पष्ट निर्देश देने के लिए नहीं करना चाहती। यह है कि मैं क्या

हम tomcat8 चलाने के लिए और mailgun एपीआई के जर्सी वेब सेवाओं के माध्यम से कनेक्ट किया है। मैंने इन उपयोगकर्ताओं के निर्देशों का पालन किया और यह ठीक काम किया। उम्मीद है कि यह किसी की मदद करता है।

1/22 पर, हम सिमेंटेक के PKI बुनियादी ढांचे अविश्वसनीय बनने के लिए सेट की वजह से हमारे SSL प्रमाणपत्र अपडेट किया गया। जावा के कुछ पुराने संस्करणों में "डिजीकर्ट ग्लोबल रूट जी 2" सीए नहीं है। अपने "cacerts" फ़ाइल में

आयात "DigiCert वैश्विक रूट G2" सीए:

कई विकल्प हैं। अपने जेआरई को 8u91 (या उच्चतर) में अपग्रेड करें, जिसमें यह रूट शामिल है। "DigiCert वैश्विक रूट G2" आप https://www.digicert.com/digicert-root-certificates.htm से जड़ डाउनलोड कर सकते हैं आयात करने के लिए। सुनिश्चित करें कि आप सही रूट प्रमाणपत्र डाउनलोड कर रहे हैं।

एक बार प्रमाण पत्र डाउनलोड किया जाता है, तो आपको निम्न जैसी कमांड के साथ में आयात करने की आवश्यकता होगी:

Keytool आयात -trustcacerts -keystore/path/to/cacerts -storepass changeit -noprompt -alias DigiCert ग्लोबल-रूट G2 -file /path/to/digicert.crt आप अपने जावा keyStore के लिए पथ और मूल प्रमाणपत्र आप डाउनलोड की का स्थान निर्धारित करने की आवश्यकता होगी।


तो 1. /path/to/digicert.crt फ़ाइल तुम सिर्फ डाउनलोड किया है। 2।/ पथ/से/cacerts - यह आपके जेआरई पथ में है। मैं "cacerts -print" ढूंढता/नाम देता हूं, इससे आपको अपने फाइल सिस्टम पर सभी जावा कैकर्ट्स को तुरंत ढूंढने में मदद मिलेगी। मेरे लिए यह था/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/cacerts

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