जावा क्लाइंट में सर्वर के स्व-हस्ताक्षरित एसएसएल प्रमाणपत्र स्वीकार करें


215

यह एक मानक प्रश्न जैसा दिखता है, लेकिन मुझे कहीं भी स्पष्ट निर्देश नहीं मिले।

मेरे पास जावा कोड है जो संभवत: स्व-हस्ताक्षरित (या समाप्त) प्रमाण पत्र के साथ एक सर्वर से जुड़ने की कोशिश कर रहा है। कोड निम्नलिखित त्रुटि की रिपोर्ट करता है:

[HttpMethodDirector] I/O exception (javax.net.ssl.SSLHandshakeException) caught 
when processing request: sun.security.validator.ValidatorException: PKIX path 
building failed: sun.security.provider.certpath.SunCertPathBuilderException: 
unable to find valid certification path to requested target

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

इस समस्या को ठीक करने के सभी निर्देश मान लेते हैं कि मैं पूरी तरह से चाबी के साथ कुशल हूं, जैसे कि

सर्वर के लिए निजी कुंजी उत्पन्न करें और इसे कीस्टोर में आयात करें

क्या कोई ऐसा व्यक्ति है जो विस्तृत निर्देश पोस्ट कर सकता है?

मैं यूनिक्स चला रहा हूं, इसलिए बैश स्क्रिप्ट सबसे अच्छी होगी।

यकीन नहीं है कि यह महत्वपूर्ण है, लेकिन कोड jboss में निष्पादित किया गया।


2
देखें कि मैं जावा HttpsURLConnection के साथ स्व-हस्ताक्षरित प्रमाणपत्र कैसे स्वीकार करूं? । जाहिर है, यह बेहतर होगा कि आप साइट को एक वैध प्रमाण पत्र का उपयोग करने के लिए प्राप्त कर सकते हैं।
मैथ्यू फ्लैशेन

2
लिंक के लिए धन्यवाद, मैंने इसे खोजते समय नहीं देखा। लेकिन दोनों समाधानों में अनुरोध भेजने के लिए विशेष कोड शामिल है और मैं मौजूदा कोड (जावा के लिए अमेज़ॅन डब्ल्यूएस क्लाइंट) का उपयोग कर रहा हूं। क्रमशः, यह उनकी साइट है जिसे मैं कनेक्ट कर रहा हूं और मैं इसकी प्रमाणपत्र समस्याओं को ठीक नहीं कर सकता।
निकिता रायबाक

2
@MatthewFlaschen - "जाहिर है, यह बेहतर होगा कि आप साइट को एक वैध प्रमाण पत्र का उपयोग करने के लिए प्राप्त कर सकते हैं ..." - यदि ग्राहक इस पर भरोसा करता है तो स्वयं हस्ताक्षरित प्रमाण पत्र एक वैध प्रमाण पत्र है। कई लोग सीए / ब्राउज़र कार्टेल पर भरोसा करना एक सुरक्षा दोष मानते हैं।
jww

3
संबंधित, दुनिया में सबसे खतरनाक कोड देखें : गैर-ब्राउज़र सॉफ़्टवेयर में एसएसएल प्रमाणपत्रों को मान्य करना । (लिंक प्रदान किया गया है क्योंकि आपको लगता है कि उन स्पैम जवाब मिल रहे हैं जो सत्यापन अक्षम करते हैं)।
jww

जवाबों:


306

आपके पास मूल रूप से दो विकल्प हैं: अपने JVM ट्रस्टस्टोर में स्व-हस्ताक्षरित प्रमाणपत्र जोड़ें या अपने क्लाइंट को कॉन्फ़िगर करें

विकल्प 1

अपने ब्राउज़र से प्रमाणपत्र निर्यात करें और इसे अपने जेवीएम ट्रस्टस्टोर (ट्रस्ट की एक श्रृंखला स्थापित करने के लिए) में आयात करें:

<JAVA_HOME>\bin\keytool -import -v -trustcacerts
-alias server-alias -file server.cer
-keystore cacerts.jks -keypass changeit
-storepass changeit 

विकल्प 2

प्रमाणपत्र सत्यापन अक्षम करें:

// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { 
    new X509TrustManager() {     
        public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
            return new X509Certificate[0];
        } 
        public void checkClientTrusted( 
            java.security.cert.X509Certificate[] certs, String authType) {
            } 
        public void checkServerTrusted( 
            java.security.cert.X509Certificate[] certs, String authType) {
        }
    } 
}; 

// Install the all-trusting trust manager
try {
    SSLContext sc = SSLContext.getInstance("SSL"); 
    sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (GeneralSecurityException e) {
} 
// Now you can access an https URL without having the certificate in the truststore
try { 
    URL url = new URL("https://hostname/index.html"); 
} catch (MalformedURLException e) {
} 

ध्यान दें कि मैं विकल्प # 2 की बिल्कुल भी सिफारिश नहीं करता । विश्वास प्रबंधक को अक्षम करना एसएसएल के कुछ हिस्सों को हरा देता है और आपको मध्य हमलों में आदमी के लिए असुरक्षित बनाता है। विकल्प # 1 को प्राथमिकता दें या, और भी बेहतर, सर्वर एक प्रसिद्ध सीए द्वारा हस्ताक्षरित "वास्तविक" प्रमाण पत्र का उपयोग करें।


7
सिर्फ एमआईएम पर हमला नहीं। यह आपको गलत साइट से कनेक्ट करने के लिए संवेदनशील बनाता है। यह पूरी तरह से असुरक्षित है। RFC 2246 देखें। मैं इस ट्रस्टमैन को हर समय पोस्ट करने का विरोध करता हूं। यह भी अपने स्वयं के विनिर्देशन सही नहीं है।
लोर्ने का मार्किस

10
@ ईजेपी मैं वास्तव में दूसरे विकल्प की सिफारिश नहीं कर रहा हूं (मैंने इसे स्पष्ट करने के लिए अपना उत्तर अपडेट कर दिया है)। हालाँकि, इसे पोस्ट नहीं करने से कुछ भी हल नहीं होगा (यह सार्वजनिक जानकारी है) और IMHO के लिए कोई मूल्य नहीं है।
पास्कल थिवेंट

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

10
दूसरा विकल्प - जिसका आप उल्लेख नहीं करते हैं - वह है सर्वर सर्टिफिकेट को या तो स्वयं ठीक करके या फिर संबंधित सपोर्ट लोगों को कॉल करके प्राप्त करना। एकल होस्ट प्रमाणपत्र वास्तव में बहुत सस्ते हैं; स्व-हस्ताक्षरित सामान के साथ चक्कर लगाना पेनी-वार पाउंड-मूर्खता है (यानी, उन अंग्रेजी मुहावरों से परिचित नहीं है, प्राथमिकताओं का एक पूरी तरह से बेवकूफ सेट जो लगभग कुछ भी नहीं बचाने के लिए बहुत खर्च होता है)।
डोनल फेलो

2
@Rich, 6 साल देर से, लेकिन आप लॉक आइकन पर क्लिक करके फ़ायरफ़ॉक्स में सर्वर सर्टिफ़िकेट भी प्राप्त कर सकते हैं -> अधिक जानकारी -> प्रमाणपत्र देखें -> विवरण टैब -> निर्यात ... यह अच्छी तरह से छिपा हुआ है।
सिद्धार्थ

9

मैंने एक सर्टिफिकेट प्रदाता को इस समस्या का पीछा किया, जो डिफ़ॉल्ट JVM विश्वसनीय होस्ट का हिस्सा नहीं है JDK 8u74। प्रदाता www.identrust.com है , लेकिन वह वह डोमेन नहीं था जिसे मैं कनेक्ट करने का प्रयास कर रहा था। उस डोमेन ने इस प्रदाता से अपना प्रमाणपत्र प्राप्त कर लिया था। देखें विल JDK / JRE में डिफ़ॉल्ट सूची से पार जड़ कवर विश्वास? - एक युगल प्रविष्टियों को पढ़ें। यह भी देखें कि कौन से ब्राउज़र और ऑपरेटिंग सिस्टम एनक्रिप्ट करते हैं

इसलिए, जिस डोमेन में मेरी दिलचस्पी थी, उससे जुड़ने के लिए, जिसके पास एक प्रमाण पत्र था, जिसे identrust.comमैंने निम्नलिखित चरणों में जारी किया था। मूल रूप से, मुझे आइडेंटिफिकेशन.कॉम प्राप्त करना था (DST Root CA X3 JVM द्वारा विश्वसनीय होने के लिए ) प्रमाणपत्र । मैं ऐसा करने में सक्षम था Apache HttpComports 4.5 का उपयोग करना

1: पर अनिश्चित काल से प्रमाण पत्र प्राप्त करें सर्टिफिकेट चेन डाउनलोड इंस्ट्रक्शंस सर्टिफिकेटDST रूट CA X3 लिंक पर क्लिक करें ।

2: स्ट्रिंग को "DST रूट CA X3.pem" नामक फ़ाइल में सहेजें। शुरुआत और अंत में फ़ाइल में "----- BEGIN CERTIFICATE -----" और "----- END CERTIFICATE -----" लाइनों को जोड़ना सुनिश्चित करें।

3: निम्न कमांड के साथ java keystore फ़ाइल, cacerts.jks बनाएँ:

keytool -import -v -trustcacerts -alias IdenTrust -keypass yourpassword -file dst_root_ca_x3.pem -keystore cacerts.jks -storepass yourpassword

4: अपने java / (maven) एप्लिकेशन की संसाधन निर्देशिका में परिणामी cacerts.jks कीस्टोर को कॉपी करें।

5: इस फ़ाइल को लोड करने के लिए निम्न कोड का उपयोग करें और इसे Apache 4.5 HttpClient के साथ संलग्न करें। यह उन सभी डोमेन के लिए समस्या का समाधान करेगा जिनके पास उपयोग indetrust.comओरेकल से जारी किए गए प्रमाण पत्र हैं, जिसमें प्रमाण पत्र JRE डिफ़ॉल्ट कीस्टॉर में शामिल है।

SSLContext sslcontext = SSLContexts.custom()
        .loadTrustMaterial(new File(CalRestClient.class.getResource("/cacerts.jks").getFile()), "yourpasword".toCharArray(),
                new TrustSelfSignedStrategy())
        .build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslcontext,
        new String[] { "TLSv1" },
        null,
        SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom()
        .setSSLSocketFactory(sslsf)
        .build();

जब प्रोजेक्ट बनता है तो cacerts.jks को क्लासपाथ में कॉपी किया जाएगा और वहां से लोड किया जाएगा। मैंने इस समय, अन्य एसएसएल साइटों के खिलाफ परीक्षण नहीं किया था, लेकिन अगर इस प्रमाण पत्र में उपरोक्त कोड "चेन" हैं तो वे भी काम करेंगे, लेकिन फिर, मुझे नहीं पता।

संदर्भ: कस्टम एसएसएल संदर्भ और मैं एक जावा HttpsURLConnection के साथ स्व-हस्ताक्षरित प्रमाण पत्र कैसे स्वीकार करूं?


सवाल स्व-हस्ताक्षरित प्रमाण पत्र के बारे में है। यह उत्तर नहीं है।
लोर्ने

4
प्रश्न (और उत्तर) को थोड़ा करीब से पढ़ें।
निकोलस

9

Apache HttpClient 4.5 स्व-हस्ताक्षरित प्रमाणपत्र स्वीकार करने का समर्थन करता है:

SSLContext sslContext = SSLContexts.custom()
    .loadTrustMaterial(new TrustSelfSignedStrategy())
    .build();
SSLConnectionSocketFactory socketFactory =
    new SSLConnectionSocketFactory(sslContext);
Registry<ConnectionSocketFactory> reg =
    RegistryBuilder.<ConnectionSocketFactory>create()
    .register("https", socketFactory)
    .build();
HttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(reg);        
CloseableHttpClient httpClient = HttpClients.custom()
    .setConnectionManager(cm)
    .build();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse sslResponse = httpClient.execute(httpGet);

यह एक SSL सॉकेट फैक्ट्री का निर्माण करता है TrustSelfSignedStrategy, जो इसका उपयोग करेगा , इसे कस्टम कनेक्शन प्रबंधक के साथ पंजीकृत करता है, फिर उस कनेक्शन प्रबंधक का उपयोग करके HTTP GET करता है।

मैं उन लोगों से सहमत हूं जो "उत्पादन में ऐसा नहीं करते हैं", हालांकि उत्पादन के बाहर स्व-हस्ताक्षरित प्रमाण पत्र स्वीकार करने के लिए उपयोग-मामले हैं; हम उन्हें स्वचालित एकीकरण परीक्षणों में उपयोग करते हैं, ताकि हम उत्पादन हार्डवेयर पर नहीं चलने पर भी SSL (जैसे उत्पादन में) का उपयोग कर रहे हों।


6

डिफ़ॉल्ट सॉकेट फैक्ट्री स्थापित करने के बजाय (जो IMO एक बुरी चीज है) - यह सिर्फ आपके द्वारा खोलने वाले प्रत्येक SSL कनेक्शन के बजाय वर्तमान कनेक्शन को प्रभावित करेगा:

URLConnection connection = url.openConnection();
    // JMD - this is a better way to do it that doesn't override the default SSL factory.
    if (connection instanceof HttpsURLConnection)
    {
        HttpsURLConnection conHttps = (HttpsURLConnection) connection;
        // Set up a Trust all manager
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
        {

            public java.security.cert.X509Certificate[] getAcceptedIssuers()
            {
                return null;
            }

            public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
            {
            }

            public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
            {
            }
        } };

        // Get a new SSL context
        SSLContext sc = SSLContext.getInstance("TLSv1.2");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        // Set our connection to use this SSL context, with the "Trust all" manager in place.
        conHttps.setSSLSocketFactory(sc.getSocketFactory());
        // Also force it to trust all hosts
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        // and set the hostname verifier.
        conHttps.setHostnameVerifier(allHostsValid);
    }
InputStream stream = connection.getInputStream();

2
आपका checkServerTrustedवास्तव में प्रमाण पत्र पर भरोसा करने और गैर-विश्वसनीय प्रमाण पत्र को अस्वीकार करने के लिए आवश्यक तर्क को लागू नहीं करता है । यह कुछ अच्छा रीडिंग बना सकता है: दुनिया में सबसे खतरनाक कोड: गैर-ब्राउज़र सॉफ़्टवेयर में एसएसएल प्रमाणपत्रों को मान्य करना
jww

1
आपका getAcceptedIssuers()तरीका विशिष्टता के अनुरूप नहीं है, और यह 'समाधान' मौलिक रूप से असुरक्षित है।
लोर्ने

4

सभी प्रमाणपत्रों पर भरोसा करने का एक बेहतर विकल्प है: एक बनाएं TrustStoreजो विशेष रूप से किसी दिए गए प्रमाण पत्र पर भरोसा करता है और इसे बनाने के लिए उपयोग करता SSLContextहै जिससे SSLSocketFactoryइसे सेट करने के लिए प्राप्त किया जा सके HttpsURLConnection। यहाँ पूरा कोड है:

File crtFile = new File("server.crt");
Certificate certificate = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream(crtFile));

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("server", certificate);

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
connection.setSSLSocketFactory(sslContext.getSocketFactory());

आप वैकल्पिक KeyStoreरूप से किसी फ़ाइल से सीधे लोड कर सकते हैं या किसी भी विश्वसनीय स्रोत से X.509 प्रमाणपत्र प्राप्त कर सकते हैं।

ध्यान दें कि इस कोड के साथ, प्रमाणपत्रों का cacertsउपयोग नहीं किया जाएगा। यह विशेष रूप HttpsURLConnectionसे केवल इस विशिष्ट प्रमाणपत्र पर भरोसा करेगा।


1

सभी एसएसएल प्रमाणपत्रों पर भरोसा करें: - यदि आप परीक्षण सर्वर पर परीक्षण करना चाहते हैं तो आप एसएसएल को बाईपास कर सकते हैं। लेकिन उत्पादन के लिए इस कोड का उपयोग न करें।

public static class NukeSSLCerts {
protected static final String TAG = "NukeSSLCerts";

public static void nuke() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[] { 
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    X509Certificate[] myTrustedAnchors = new X509Certificate[0];  
                    return myTrustedAnchors;
                }

                @Override
                public void checkClientTrusted(X509Certificate[] certs, String authType) {}

                @Override
                public void checkServerTrusted(X509Certificate[] certs, String authType) {}
            }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
    } catch (Exception e) { 
    }
}

}

कृपया इस फ़ंक्शन को onCreate () फ़ंक्शन में गतिविधि या अपने एप्लिकेशन क्लास में कॉल करें।

NukeSSLCerts.nuke();

इसका उपयोग एंड्रॉइड में वॉली के लिए किया जा सकता है।


जब तक कोड काम नहीं करता, तब तक आपको पूरी तरह से यकीन नहीं है कि आपको क्यों वोट दिया जा रहा है। शायद यह धारणा है कि एंड्रॉइड किसी तरह शामिल है जब मूल प्रश्न एंड्रॉइड को टैग नहीं करता था।
लो-टैन

1

स्वीकृत उत्तर ठीक है, लेकिन मैं इसमें कुछ जोड़ना चाहूंगा क्योंकि मैं मैक पर इंटेलीजे का उपयोग कर रहा था और इसे JAVA_HOMEपथ चर का उपयोग करके काम करने के लिए नहीं मिला ।

यह पता चलता है कि इंटेलीजे से एप्लिकेशन को चलाते समय जावा होम अलग था।

यह पता लगाने के लिए कि यह कहाँ है, आप बस वही कर सकते हैं, System.getProperty("java.home")जहाँ से विश्वसनीय प्रमाणपत्र पढ़े जाते हैं।


0

यदि 'वे' एक स्व-हस्ताक्षरित प्रमाण पत्र का उपयोग कर रहे हैं तो यह उनके ऊपर है कि वे अपने सर्वर को उपयोगी बनाने के लिए आवश्यक कदम उठाएँ। विशेष रूप से इसका मतलब है कि आपके प्रमाण पत्र को विश्वसनीय तरीके से ऑफ़लाइन प्रदान करना। तो उन्हें ऐसा करने के लिए मिलता है। उसके बाद आप JSSE संदर्भ गाइड में वर्णित कीटल के उपयोग से अपने ट्रस्टस्टोर में आयात करते हैं। यहाँ पर असुरक्षित TrustManager के बारे में भी मत सोचो।

EDIT सत्रह (!) डाउनवोटर्स, और कई टिप्पणीकारों के लाभ के लिए , जिन्होंने स्पष्ट रूप से वास्तव में नहीं पढ़ा है कि मैंने यहां क्या लिखा है, यह स्व-हस्ताक्षरित प्रमाण पत्र के खिलाफ एक झिरमी नहीं है। सही तरीके से लागू होने पर स्व-हस्ताक्षरित प्रमाण पत्र के साथ कुछ भी गलत नहीं है लेकिन, उन्हें लागू करने का सही तरीका यह है कि प्रमाणपत्र को एक ऑफ़लाइन प्रक्रिया के माध्यम से सुरक्षित रूप से वितरित किया जाए , बजाय इसके कि अप्रमाणित चैनल के माध्यम से उन्हें प्रमाणित करने के लिए उपयोग किया जाए। निश्चित रूप से यह स्पष्ट है? यह निश्चित रूप से हर सुरक्षा-जागरूक संगठन के लिए स्पष्ट है, जो मैंने कभी बैंकों के लिए, हजारों शाखाओं के साथ अपनी कंपनियों के लिए काम किया है। क्लाइंट-साइड कोड-बेस 'समाधान' सभी पर भरोसा करने कास्व-हस्ताक्षरित प्रमाण-पत्र सहित, बिल्कुल किसी के द्वारा हस्ताक्षरित प्रमाण-पत्र, या कोई भी मध्यस्थ निकाय, जो स्वयं को CA के रूप में स्थापित कर रहा है, ipso वास्तविक सुरक्षित नहीं है। यह सिर्फ सुरक्षा पर खेल रहा है। यह व्यर्थ है। आप ... किसी के साथ एक निजी, छेड़छाड़, उत्तर-प्रूफ, इंजेक्शन-प्रूफ बातचीत कर रहे हैं। कोई। बीच में एक आदमी। एक आवेग करनेवाला। कोई। आप सादा ही इस्तेमाल कर सकते हैं।


2
सिर्फ इसलिए कि कुछ सर्वर ने https का उपयोग करने का फैसला किया है, इसका मतलब यह नहीं है कि क्लाइंट वाला व्यक्ति अपने स्वयं के उद्देश्यों के लिए सुरक्षा के बारे में एक बकवास देता है।
गस

3
मुझे आश्चर्य है कि यह जवाब इतना नीचे उतर गया। मैं थोड़ा और समझना पसंद करूंगा क्यों। ऐसा लगता है कि EJP सुझाव दे रहा है कि आपको विकल्प 2 नहीं करना चाहिए क्योंकि यह एक बड़ी सुरक्षा खामी की अनुमति देता है। क्या कोई समझा सकता है कि (पूर्व तैनाती सेटिंग्स के अलावा) क्यों यह उत्तर निम्न गुणवत्ता वाला है?
cr1pto

2
खैर, मुझे लगता है कि यह सब। "अपने सर्वर को प्रयोग करने योग्य बनाने के लिए आवश्यक कदम उठाने के लिए यह उन पर निर्भर करता है " ? एक सर्वर ऑपरेटर को इसे प्रयोग करने योग्य बनाने के लिए क्या करना होगा? आपके मन में क्या कदम हैं? क्या आप उनमें से एक सूची प्रदान कर सकते हैं? लेकिन 1,000 फीट पीछे हटना, ओपी द्वारा पूछे गए समस्या से कैसे संबंधित है? वह जानना चाहता है कि क्लाइंट को जावा में स्व-हस्ताक्षरित प्रमाणपत्र कैसे स्वीकार करना है। क्योंकि ओपी सर्टिफिकेट स्वीकार्य है, कोड में विश्वास कायम रखने का यह एक साधारण मामला है।
jww

2
@EJP - अगर मैं गलत हूं, तो मुझे सुधारें, लेकिन स्व-हस्ताक्षरित प्रमाणपत्र स्वीकार करना क्लाइंट साइड पॉलिसी निर्णय है। इसका सर्वर साइड ऑपरेशंस से कोई लेना-देना नहीं है। ग्राहक को निर्णय लेना चाहिए। प्रमुख वितरण समस्या को हल करने के लिए समता को एक साथ काम करना चाहिए, लेकिन इसका सर्वर को उपयोग करने योग्य बनाने से कोई लेना-देना नहीं है।
jww

3
@ ईजेपी - मैंने निश्चित रूप से नहीं कहा, "सभी प्रमाणपत्रों पर भरोसा करें" । शायद मुझे कुछ याद आ रहा है (या आप चीजों में बहुत ज्यादा पढ़ रहे हैं) ... ओपी के पास प्रमाण पत्र है, और उसके लिए स्वीकार्य है। वह जानना चाहता है कि इस पर कैसे भरोसा किया जाए। मैं शायद बालों को विभाजित कर रहा हूं, लेकिन प्रमाण पत्र को ऑफ़लाइन वितरित करने की आवश्यकता नहीं है। एक आउट-ऑफ-बैंड सत्यापन का उपयोग किया जाना चाहिए, लेकिन यह "क्लाइंट ऑफ़लाइन पर वितरित किया जाना चाहिए" जैसा नहीं है । वह सर्वर और क्लाइंट का निर्माण करने वाली दुकान भी हो सकती है, इसलिए उसके पास एक प्राथमिक ज्ञान है।
jww

0

यह पूरी समस्या का हल नहीं है, लेकिन ओरेकल के पास इस केटूल का उपयोग करने के बारे में अच्छे विस्तृत दस्तावेज हैं। यह कैसे समझाता है

  1. कीटूल का उपयोग करें।
  2. Keytool का उपयोग कर सेर / सेल्फ हस्ताक्षरित सेरेट उत्पन्न करें।
  3. आयात जावा ग्राहकों के लिए तैयार की जाती है।

https://docs.oracle.com/cd/E54932_01/doc.705/e54936/cssg_create_ssl_cert.htm#CSVSG178


0

शीर्ष टिप्पणी द्वारा सुझाए गए केटूल का उपयोग करने के बजाय, आरएचईएल पर आप आरएचईएल के नए संस्करणों में शुरू होने वाले अपडेट-सीए-ट्रस्ट का उपयोग कर सकते हैं 6. आपको पेम प्रारूप में प्रमाण पत्र की आवश्यकता होगी। फिर

trust anchor <cert.pem>

/Etc/pki/ca-trust/source/cert.p11-kit संपादित करें और "प्रमाणपत्र श्रेणी: अन्य-प्रविष्टि" को "प्रमाणपत्र श्रेणी: प्राधिकरण" में बदलें। (या स्क्रिप्ट में ऐसा करने के लिए sed का उपयोग करें।) फिर करें

update-ca-trust

कुछ युगल:

  • मुझे अपने RHEL 6 सर्वर पर "विश्वास" नहीं मिला और yum ने इसे स्थापित करने की पेशकश नहीं की। मैंने इसे RHEL 7 सर्वर पर उपयोग किया और .p11-kit फ़ाइल की प्रतिलिपि बनाई।
  • आपके लिए यह काम करने के लिए, आपको करने की आवश्यकता हो सकती है update-ca-trust enable । यह / etc / pki / java / cacerts को प्रतीकात्मक लिंक के साथ / etc / pki / ca-trust / extracted / java / cacerts की जगह लेगा। (तो आप पहले वाला बैकअप लेना चाहते हैं।)
  • यदि आपका जावा क्लाइंट किसी अन्य स्थान पर संग्रहीत कैसैटर्स का उपयोग करता है, तो आप इसे मैन्युअल रूप से सिमलिंक के साथ / etc / pki / ca-trust / extracted / java / cacerts में बदल सकते हैं, या इसे उस फ़ाइल से बदल सकते हैं।

0

मेरे पास यह मुद्दा था कि मैं एक पुस्तकालय में एक URL पारित कर url.openConnection();रहा था, जिसे मैं jon-daniel का उत्तर अनुकूलित कह रहा था ,

public class TrustHostUrlStreamHandler extends URLStreamHandler {

    private static final Logger LOG = LoggerFactory.getLogger(TrustHostUrlStreamHandler.class);

    @Override
    protected URLConnection openConnection(final URL url) throws IOException {

        final URLConnection urlConnection = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile()).openConnection();

        // adapated from
        // /programming/2893819/accept-servers-self-signed-ssl-certificate-in-java-client
        if (urlConnection instanceof HttpsURLConnection) {
            final HttpsURLConnection conHttps = (HttpsURLConnection) urlConnection;

            try {
                // Set up a Trust all manager
                final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    @Override
                    public void checkClientTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {
                    }

                    @Override
                    public void checkServerTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {
                    }
                } };

                // Get a new SSL context
                final SSLContext sc = SSLContext.getInstance("TLSv1.2");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                // Set our connection to use this SSL context, with the "Trust all" manager in place.
                conHttps.setSSLSocketFactory(sc.getSocketFactory());
                // Also force it to trust all hosts
                final HostnameVerifier allHostsValid = new HostnameVerifier() {
                    @Override
                    public boolean verify(final String hostname, final SSLSession session) {
                        return true;
                    }
                };

                // and set the hostname verifier.
                conHttps.setHostnameVerifier(allHostsValid);

            } catch (final NoSuchAlgorithmException e) {
                LOG.warn("Failed to override URLConnection.", e);
            } catch (final KeyManagementException e) {
                LOG.warn("Failed to override URLConnection.", e);
            }

        } else {
            LOG.warn("Failed to override URLConnection. Incorrect type: {}", urlConnection.getClass().getName());
        }

        return urlConnection;
    }

}

इस वर्ग का उपयोग करके एक नया URL बनाना संभव है:

trustedUrl = new URL(new URL(originalUrl), "", new TrustHostUrlStreamHandler());
trustedUrl.openConnection();

इसका यह लाभ है कि यह स्थानीयकृत है और डिफ़ॉल्ट को प्रतिस्थापित नहीं करता है URL.openConnection

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.