"Java.security.cert.CertificateException" को कैसे ठीक करें: कोई वैकल्पिक विषय उपस्थित नहीं है "त्रुटि?


108

मेरे पास एक जावा वेब सेवा क्लाइंट है, जो HTTPS के माध्यम से एक वेब सेवा का उपभोग करता है।

import javax.xml.ws.Service;

@WebServiceClient(name = "ISomeService", targetNamespace = "http://tempuri.org/", wsdlLocation = "...")
public class ISomeService
    extends Service
{

    public ISomeService() {
        super(__getWsdlLocation(), ISOMESERVICE_QNAME);
    }

जब मैं सेवा URL से जुड़ता हूं (https://AAA.BBB.CCC.DDD:9443/ISomeService ), मुझे अपवाद मिलता है java.security.cert.CertificateException: No subject alternative names present

इसे ठीक करने के लिए, मैंने पहली बार openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txtफ़ाइल में निम्न सामग्री चलाई और प्राप्त की certs.txt:

CONNECTED(00000003)
---
Certificate chain
 0 s:/CN=someSubdomain.someorganisation.com
   i:/CN=someSubdomain.someorganisation.com
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=someSubdomain.someorganisation.com
issuer=/CN=someSubdomain.someorganisation.com
---
No client certificate CA names sent
---
SSL handshake has read 489 bytes and written 236 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 512 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-MD5            
    Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Session-ID-ctx:                 
    Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Key-Arg   : None
    Start Time: 1382521838
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---

AFAIK, अब मुझे जरूरत है

  1. के certs.txtबीच का हिस्सा निकालें-----BEGIN CERTIFICATE-----और-----END CERTIFICATE----- , और
  2. इसे संशोधित करें ताकि प्रमाणपत्र नाम AAA.BBB.CCC.DDDऔर के बराबर हो
  3. फिर परिणाम का उपयोग करके आयात करें keytool -importcert -file fileWithModifiedCertificate(जहां fileWithModifiedCertificateसंचालन 1 और 2 का परिणाम है)।

क्या ये सही है?

यदि हां, तो मैं आईपी-आधारित Adddress ( AAA.BBB.CCC.DDD) के साथ चरण 1 से प्रमाण पत्र कैसे बना सकता हूं ?

अपडेट 1 (23.10.2013 15:37 MSK): इसी तरह के प्रश्न के उत्तर में , मैंने निम्नलिखित पढ़ा:

यदि आप उस सर्वर के नियंत्रण में नहीं हैं, तो इसके होस्ट नाम का उपयोग करें (बशर्ते कि कम से कम एक CN मिलान हो जो मौजूदा प्रमाणपत्र में होस्ट नाम हो)।

वास्तव में "उपयोग" का क्या अर्थ है?

जवाबों:


153

मैंने यहां प्रस्तुत दृष्टिकोण का उपयोग करके HTTPS चेक को अक्षम करके समस्या को ठीक किया :

मैंने ISomeServiceकक्षा में निम्नलिखित कोड डाला :

static {
    disableSslVerification();
}

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

        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }
}

चूंकि मैं https://AAA.BBB.CCC.DDD:9443/ISomeServiceकेवल परीक्षण उद्देश्यों के लिए उपयोग कर रहा हूं , यह एक अच्छा पर्याप्त समाधान है।


ऊपर वर्णित लिंक में उल्लिखित दृष्टिकोण अवरुद्ध प्रतीत होता है ( nakov.com/blog/2009/07/16/… )। क्या कोई लिंक को अपडेट कर सकता है?
जॉन

मैंने इस प्रक्रिया को करने वाले सत्यापन को अक्षम करने की कोशिश की, लेकिन एसएसएल प्रोटोकॉल (पूडल भेद्यता) के लिए ब्राउज़र सत्यापन मुझे देता है: ssl_error_no_cypher_overlap। कोई विचार?
--२४

नमस्कार, मुझे

73
HTTPS चेक को अक्षम करना "समाधान" नहीं है। आपको कहना चाहिए कि मुझे "पैच" मिला।
जुस १२

2
यह Pre_prod और उत्पादन पर भेद्यता का कारण होगा। 1. विंडो होस्ट फ़ाइल पर होस्ट एंट्री करें 2. या फिर सेर्ट्स में सब्जेक्ट के वैकल्पिक नाम फ़ील्ड्स में IP या FQDN नाम जोड़ें
शंकर

34

मेरे पास एक ही समस्या है और इस कोड के साथ हल किया गया है। मैंने अपने webservices में पहली कॉल से पहले यह कोड डाला।

javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){

    public boolean verify(String hostname,
            javax.net.ssl.SSLSession sslSession) {
        return hostname.equals("localhost");
    }
});

यह सरल है और ठीक काम करता है।

यहाँ मूल स्रोत है।


3
या आप बस सत्यापित () फ़ंक्शन के पूरे शरीर को बदल सकते हैं return hostname.equals("localhost");, यदि आप ऐसा करना चाहते हैं। ifपूरी तरह से ज़रूरत से ज़्यादा है।
बजे एक CVn

यह एक सरल और त्वरित समाधान था जो हमें एक विक्रेता के परीक्षण वातावरण में परीक्षण के आसपास मिला था, जिसमें एक उचित प्रमाण पत्र नहीं था। बहुत - बहुत धन्यवाद!
dacDave

@ JuanM.Hidalgo ने मेरे लिए काम किया, कॉल से ठीक पहले कोड ऊपर रखा HttpsURLConnection connection = (HttpsURLConnection) obj.openConnection();। इसके अलावा, क्या यह हर प्रमाण पत्र की उपेक्षा करता है? चूँकि मैंने देखा कि इस तरह का वर्कअराउंड सुरक्षा के प्रति संवेदनशील है। धन्यवाद!
थंडरवेरिंग

इस उत्तर ने मेरे एसएसएल प्रमाणित अपवाद और गैर एलडीएच पात्रों के मुद्दे को हल कर दिया, मैं देख सकता था कि खुले जेडीके
अखिल कामथ

28

यह एक पुराना सवाल है, फिर भी मुझे JDK 1.8.0_144 से jdk 1.8.0_191 पर जाने पर यही समस्या थी

हमें चैंज में एक संकेत मिला:

बदलाव का

हमने निम्नलिखित अतिरिक्त सिस्टम प्रॉपर्टी को जोड़ा, जिसने इस मामले को हल करने में हमारे मामले में मदद की:

-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true

25

प्रमाणपत्र पहचान का सत्यापन ग्राहक द्वारा किए गए अनुरोधों के विरुद्ध किया जाता है।

जब आपका क्लाइंट उपयोग करता है https://xxx.xxx.xxx.xxx/something(जहां xxx.xxx.xxx.xxxएक आईपी पता है), तो इस आईपी पते के खिलाफ प्रमाण पत्र की पहचान की जांच की जाती है (सिद्धांत में, केवल एक आईपी सैन एक्सटेंशन का उपयोग करके)।

यदि आपके प्रमाणपत्र में कोई IP SAN नहीं है, लेकिन DNS SAN (या यदि कोई DNS SAN, विषय DN में एक सामान्य नाम) नहीं है, तो आप अपने क्लाइंट को उस होस्ट नाम के साथ URL का उपयोग करके काम करने के लिए इसे प्राप्त कर सकते हैं (या एक होस्ट नाम जिसके लिए प्रमाणपत्र वैध होगा, यदि कई संभावित मूल्य हैं)। उदाहरण के लिए, यदि आपके पास प्रमाणित नाम है www.example.com, तो उपयोग करें https://www.example.com/something

बेशक, आपको उस आईपी पते को हल करने के लिए उस होस्ट नाम की आवश्यकता होगी।

इसके अतिरिक्त, यदि कोई DNS SAN हैं, तो Sub DN में CN को अनदेखा किया जाएगा, इसलिए इस मामले में DNS SAN में से एक से मेल खाने वाले नाम का उपयोग करें।


1
मैं इस सेवा तक नहीं पहुंच सकता http://www.example.com/someservice। यह आईपी आधारित पता (के साथ काम करने के लिए प्रमाण पत्र के लिए यह सही है क्रम में https://AAA.BBB.CCC.DDD:9443/ISomeService), मैं पूरी तरह से तैयार की जरूरत CNके लिए क्षेत्रों AAA.BBB.CCC.DDD(बदलने के someSubdomain.someorganisation.comद्वारा AAA.BBB.CCC.DDDऊपर फाइल में) और जिसके परिणामस्वरूप प्रमाण पत्र फ़ाइल आयात?
मेंटिफ्लेक्सेक्स

यदि आप सर्वर के नियंत्रण में नहीं हैं तो आप CN या प्रमाणपत्र के बारे में कुछ नहीं कर सकते।
ब्रूनो

परीक्षण के उद्देश्यों के लिए आईपी पते पर पहुंचने के लिए आप अस्थायी रूप से अपनी /etc/hostsफ़ाइल या समकक्ष को संशोधित कर सकते हैं
tyoc213 19

1
मेरे कोड में मैं एक सार्वजनिक आईपी को अनुरोध भेज रहा था, लेकिन प्रमाण पत्र सीएन एक मेजबान नाम था। इसलिए मेरे कोड में, मैंने होस्टनाम द्वारा आईपी को बदल दिया, और इस होस्टनाम को आईपी से जोड़ने के लिए मेरे / etc / मेजबान को कॉन्फ़िगर किया। हल किया !
लियोपोल्ड गॉल्ट

15

प्रमाणपत्र आयात करने के लिए:

  1. सर्वर से सर्टिफिकेट निकालें, उदाहरण के लिए, openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txtयह पीईएम फॉर्मेट में सेर्ट्स निकाल देगा।
  2. प्रमाणपत्र को DER प्रारूप में रूपांतरित करें क्योंकि यह कुंजीटूल अपेक्षा करता है, जैसे openssl x509 -in certs.txt -out certs.der -outform DER
  3. अब आप इस प्रमाणपत्र को सिस्टम डिफ़ॉल्ट 'कैसर्ट' फ़ाइल में आयात करना चाहते हैं। अपने जावा इंस्टॉलेशन के लिए सिस्टम डिफॉल्ट 'कैसर्ट' फाइल का पता लगाएँ। एक नज़र डालें कि डिफ़ॉल्ट जावा इंस्टॉलेशन के कैसर्ट का स्थान कैसे प्राप्त करें?
  4. उस कैसर्ट फ़ाइल में सेर्ट्स आयात करें: sudo keytool -importcert -file certs.der -keystore <path-to-cacerts>डिफॉल्ट कैसर्ट पासवर्ड 'चेंजिट' है।

यदि प्रमाणपत्र FQDN के लिए जारी किया गया है और आप अपने जावा कोड में IP पते से जुड़ने का प्रयास कर रहे हैं, तो यह संभवत: प्रमाणपत्र के साथ गड़बड़ करने के बजाय आपके कोड में तय किया जाना चाहिए। FQDN द्वारा कनेक्ट करने के लिए अपना कोड बदलें। यदि FQDN आपके देव मशीन पर resolvable नहीं है, तो बस इसे अपने होस्ट फ़ाइल में जोड़ें, या अपनी मशीन को DNS सर्वर से कॉन्फ़िगर करें जो इस FQDN को हल कर सकता है।


"यदि FQDN आपके देव मशीन पर resolvable नहीं है, तो बस इसे अपने होस्ट फ़ाइल में जोड़ें" - मदद की। आपका बहुत बहुत धन्यवाद!
वूलैंड

मैंने वही किया लेकिन फिर भी यह मुद्दा कायम है। क्या इस दृष्टिकोण का उपयोग करके कुछ और किया जा सकता है?
pkgajulapalli

9

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

कदम से कदम समझने के लिए कृपया इस लिंक को देखें

उपरोक्त त्रुटि का अर्थ है कि आपकी JKS फाइल उस आवश्यक डोमेन को याद कर रही है जिस पर आप एप्लिकेशन को एक्सेस करने का प्रयास कर रहे हैं। आपको कई डोमेन जोड़ने के लिए Open SSL और कुंजी टूल का उपयोग करना होगा

  1. एक मौजूदा डायरेक्टरी में खुलता है
  2. echo '[ subject_alt_name ]' >> openssl.cnf
  3. echo 'subjectAltName = DNS:example.mydomain1.com, DNS:example.mydomain2.com, DNS:example.mydomain3.com, DNS: localhost'>> openssl.cnf
  4. openssl req -x509 -nodes -newkey rsa:2048 -config openssl.cnf -extensions subject_alt_name -keyout private.key -out self-signed.pem -subj '/C=gb/ST=edinburgh/L=edinburgh/O=mygroup/OU=servicing/CN=www.example.com/emailAddress=postmaster@example.com' -days 365
  5. सार्वजनिक कुंजी (। Pem) फ़ाइल को PKS12 प्रारूप में निर्यात करें। यह आपको पासवर्ड के लिए संकेत देगा

    openssl pkcs12 -export -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -export -in
    self-signed.pem -inkey private.key -name myalias -out keystore.p12
  6. स्व-हस्ताक्षरित PEM (Keystore) से a.JKS बनाएँ

    keytool -importkeystore -destkeystore keystore.jks -deststoretype PKCS12 -srcstoretype PKCS12 -srckeystore keystore.p12
  7. Keystore या JKS फ़ाइल के ऊपर से एक प्रमाणपत्र बनाएँ

    keytool -export -keystore keystore.jks -alias myalias -file selfsigned.crt
  8. चूँकि उपर्युक्त प्रमाण पत्र स्व हस्ताक्षरित है और सीए द्वारा मान्य नहीं है, इसलिए इसे विंडोज़ के लिए मैक के लिए नीचे के स्थान में ट्रस्टस्टोर (कैसर्ट फ़ाइल में जोड़ा जाना चाहिए), यह पता करें कि आपका जेडडीके कहाँ स्थापित है।)

    sudo keytool -importcert -file selfsigned.crt -alias myalias -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts

मूल उत्तर यहां इस लिंक पर पोस्ट किया गया है


4

आप सभी ssl सत्यापन को अक्षम नहीं करना चाहते हैं और इसलिए आप इसके माध्यम से hostName सत्यापन को अक्षम कर सकते हैं जो कि विकल्प से थोड़ा कम डरावना है:

HttpsURLConnection.setDefaultHostnameVerifier(
    SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

[संपादित करें]

जैसा कि conapart3 ने उल्लेख किया SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERहै, अब इसे हटा दिया गया है, इसलिए इसे बाद के संस्करण में हटाया जा सकता है, इसलिए आपको भविष्य में अपना स्वयं का रोल करने के लिए मजबूर किया जा सकता है, हालांकि मैं अभी भी कहूंगा कि मैं किसी भी समाधान से दूर हो जाऊंगा जहां सभी सत्यापन बंद हैं।


2
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERअब पदावनत हो गया है।
conapart3

3

इस त्रुटि को प्राप्त करने के साथ मेरी समस्या का समाधान सिर्फ "qatest / webService" के बजाय पूर्ण URL "qatest.ourCompany.com/webService" का उपयोग करके किया गया था। कारण यह था कि हमारे सुरक्षा प्रमाणपत्र में वाइल्डकार्ड था "" .our .Company.com "। एक बार जब मैंने पूरा पता लगाया तो अपवाद दूर चला गया। उम्मीद है की यह मदद करेगा।


2

इसका उत्तर https://stackoverflow.com/a/53491151/1909708 पर पहले ही दे चुके हैं ।

यह विफल हो जाता है क्योंकि न तो प्रमाणपत्र सामान्य नाम ( CNप्रमाणन में Subject) और न ही वैकल्पिक नामों में से कोई भी ( Subject Alternative Nameप्रमाणपत्र में) लक्ष्य होस्टनाम या आईपी एड्रेस के साथ मेल खाता है।

उदाहरण के लिए, एक JVM से, जब एक IP पते ( WW.XX.YY.ZZ) और DNS नाम ( https://stackoverflow.com ) से कनेक्ट करने की कोशिश की जा रही है , तो HTTPS कनेक्शन विफल हो जाएगा क्योंकि जावा ट्रस्टस्टोर में संग्रहीत प्रमाणपत्र cacertsसामान्य नाम (या) की उम्मीद करता है प्रमाणपत्र वैकल्पिक नाम जैसे stackexchange.com या * .stackoverflow.com आदि) लक्ष्य पते से मेल खाने के लिए।

कृपया देखें: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#HostnameVerifier

    HttpsURLConnection urlConnection = (HttpsURLConnection) new URL("https://WW.XX.YY.ZZ/api/verify").openConnection();
    urlConnection.setSSLSocketFactory(socketFactory());
    urlConnection.setDoOutput(true);
    urlConnection.setRequestMethod("GET");
    urlConnection.setUseCaches(false);
    urlConnection.setHostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession sslSession) {
            return true;
        }
    });
    urlConnection.getOutputStream();

ऊपर, एक कार्यान्वित HostnameVerifierवस्तु को पारित किया जो हमेशा रिटर्न होता है true:

new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession sslSession) {
            return true;
        }
    }

1

वसंत बूट के लिए RestTemplate:

  • org.apache.httpcomponents.httpcoreनिर्भरता जोड़ें
  • NoopHostnameVerifierएसएसएल कारखाने के लिए उपयोग :

    SSLContext sslContext = new SSLContextBuilder()
            .loadTrustMaterial(new URL("file:pathToServerKeyStore"), storePassword)
    //        .loadKeyMaterial(new URL("file:pathToClientKeyStore"), storePassword, storePassword)
            .build();
    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(client);
    RestTemplate restTemplate = new RestTemplate(factory);

0

यह त्रुटि संदेश मिलने के बाद मुझे यह प्रश्न मिला। हालाँकि मेरे मामले में हमारे पास अलग-अलग उप-डोमेन ( http://example1.xxx.com/someservice और http://example2.yyy.com/someservice ) के साथ दो URL थे जो एक ही सर्वर को निर्देशित किए गए थे। इस सर्वर में * .xxx.com डोमेन के लिए केवल एक वाइल्डकार्ड प्रमाणपत्र था। दूसरे डोमेन के माध्यम से सेवा का उपयोग करते समय, पाया गया प्रमाणित (* .xxx.com) अनुरोधित डोमेन (* .yyy.com) के साथ मेल नहीं खाता है और त्रुटि उत्पन्न होती है।

इस मामले में हमें एसएसएल सुरक्षा को कम करके इस तरह के एक गलत तरीके को ठीक करने की कोशिश नहीं करनी चाहिए, लेकिन इस पर सर्वर और प्रमाणपत्र की जांच करनी चाहिए।


0
public class RESTfulClientSSL {

    static TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            // TODO Auto-generated method stub
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            // TODO Auto-generated method stub
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            // TODO Auto-generated method stub
            return null;
        }
    }};

    public class NullHostNameVerifier implements HostnameVerifier {
        /*
         * (non-Javadoc)
         *
         * @see javax.net.ssl.HostnameVerifier#verify(java.lang.String,
         * javax.net.ssl.SSLSession)
         */
        @Override
        public boolean verify(String arg0, SSLSession arg1) {
            // TODO Auto-generated method stub
            return true;
        }
    }

    public static void main(String[] args) {

        HttpURLConnection connection = null;
        try {

            HttpsURLConnection.setDefaultHostnameVerifier(new RESTfulwalkthroughCer().new NullHostNameVerifier());
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());


            String uriString = "https://172.20.20.12:9443/rest/hr/exposed/service";
            URL url = new URL(uriString);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            //connection.setRequestMethod("POST");

            BASE64Encoder encoder = new BASE64Encoder();
            String username = "admin";
            String password = "admin";
            String encodedCredential = encoder.encode((username + ":" + password).getBytes());
            connection.setRequestProperty("Authorization", "Basic " + encodedCredential);

            connection.connect();
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                StringBuffer stringBuffer = new StringBuffer();
                String line = "";
                while ((line = reader.readLine()) != null) {
                    stringBuffer.append(line);
                }
                String content = stringBuffer.toString();
                System.out.println(content);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }
}

1
कृपया अपने कोड में व्याख्यात्मक पाठ जोड़ें। देखें stackoverflow.com/help/how-to-answer
jasie

1
यह एक सुरक्षा दोष है। यह पहली बार में प्रमाणपत्र सत्यापन को कैसे निष्क्रिय करता है। जो भी इस समाधान को कॉपी-पेस्ट करते हैं, वे अपने सॉफ़्टवेयर में एक सुरक्षा बग बनाएंगे।
मारेक पुचलस्की

0

मैं स्प्रिंगबूट में 2 तरह एसएसएल के माध्यम से जा रहा था। मैंने सभी सही विन्यास सेवा टॉमकैट सर्वर और सर्विस कॉलर रेस्टेमप्लेट बनाया है। लेकिन मैं के रूप में त्रुटि हो रही थी "java.security.cert.CertificateException: के : कोई भी विषय वैकल्पिक नाम मौजूद नहीं था"

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

अब, इसे जेवीएम से कैसे जोड़ा जाए।

jre / lib / security / cacerts फ़ाइल पर जाएं। हमें jvm की इस कैसर्ट फाइल में अपनी सर्वर सर्टिफिकेट फाइल को जोड़ना होगा।

विंडोज में कमांड लाइन के माध्यम से कैसर्ट फाइल में सर्वर सर्टिफिकेट जोड़ने की कमांड।

C: \ Program Files \ Java \ jdk1.8.0_191 \ jre \ lib \ Security> keytool -import -noprompt -trustcacerts -alias sslserver -file E: a spring_cloud_sachin \ ssl_keys \ sslserver.cer -keystore cacertore

सर्वर प्रमाणपत्र स्थापित है या नहीं इसकी जाँच करें:

C: \ Program Files \ Java \ jdk1.8.0_191 \ jre \ lib \ Security> कीटूल-लिस्ट -स्केस्टर कैसर्ट

आप स्थापित प्रमाणपत्रों की सूची देख सकते हैं:

अधिक जानकारी के लिए: https://sachin4java.blogspot.com/2019/08/javasecuritycertcertificateexception-no.html


0

प्रमाणपत्र में CN के अनुरूप IP के साथ होस्ट प्रविष्टि जोड़ें

सीएन = someSubdomain.someorganisation.com

अब CN नाम के साथ IP को अपडेट करें जहां आप url एक्सेस करने का प्रयास कर रहे हैं।

इसने मेरे लिए काम किया।


0

यह कोड आकर्षण की तरह काम करेगा और बाकी कोड के लिए restTemple ऑब्जेक्ट का उपयोग करेगा।

  RestTemplate restTemplate = new RestTemplate();   
  TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) {
                return true;
            }

        };

        SSLContext sslContext = null;
        try {
            sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy)
                    .build();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);

        restTemplate.setRequestFactory(requestFactory);
}

0

जब आपके पास CN और विषय वैकल्पिक नाम (SAN) दोनों के साथ एक प्रमाण पत्र होता है, यदि आप CN सामग्री के आधार पर अपना अनुरोध करते हैं, तो उस विशेष सामग्री को भी SAN के तहत मौजूद होना चाहिए, अन्यथा यह प्रश्न में त्रुटि के साथ विफल हो जाएगा।

मेरे मामले में CN के पास कुछ था, SAN के पास कुछ और था। मुझे SAN URL का उपयोग करना था, और फिर यह ठीक काम किया।


-3

होस्ट्स फ़ाइल में अपना आईपी पता जोड़ें। जो C: \ Windows \ System32 \ driver \ etc के फ़ोल्डर में है। आईपी ​​पते के आईपी और डोमेन नाम भी जोड़ें। उदाहरण: aaa.bbb.ccc.ddd abc@def.com


-5

मैंने निम्नलिखित तरीके से समस्या को हल किया है।

1. एक वर्ग बनाना। कक्षा में कुछ खाली कार्यान्वयन हैं

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

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

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

@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString)
        throws CertificateException {
    // TODO Auto-generated method stub

}

@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString)
        throws CertificateException {
    // TODO Auto-generated method stub

}

2. एक विधि बनाना

private static void disableSSL() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[] { new MyTrustManager() };

        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

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