Bagaimana cara memperbaiki kesalahan "java.security.cert.CertificateException: Tidak ada nama alternatif subjek"?

108

Saya memiliki klien layanan web Java, yang menggunakan layanan web melalui 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);
    }

Ketika saya terhubung ke URL layanan ( https://AAA.BBB.CCC.DDD:9443/ISomeService), saya mendapatkan pengecualian java.security.cert.CertificateException: No subject alternative names present.

Untuk memperbaikinya, saya pertama kali menjalankan openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txtdan mendapatkan konten berikut dalam file 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, sekarang saya perlu

  1. ekstrak bagian certs.txtantara -----BEGIN CERTIFICATE-----dan -----END CERTIFICATE-----,
  2. memodifikasinya sehingga nama sertifikat sama dengan AAA.BBB.CCC.DDDdan
  3. kemudian impor hasil menggunakan keytool -importcert -file fileWithModifiedCertificate(di mana fileWithModifiedCertificateadalah hasil operasi 1 dan 2).

Apakah ini benar?

Jika demikian, bagaimana tepatnya saya dapat membuat sertifikat dari langkah 1 bekerja dengan alamat alamat IP ( AAA.BBB.CCC.DDD)?

Pembaruan 1 (23.10.2013 15:37 MSK): Sebagai jawaban atas pertanyaan serupa , saya membaca yang berikut ini:

Jika Anda tidak mengontrol server itu, gunakan nama host-nya (asalkan setidaknya ada CN yang cocok dengan nama host itu di sertifikat yang ada).

Apa sebenarnya arti "menggunakan"?

Mentiflectax
sumber

Jawaban:

153

Saya memperbaiki masalah dengan menonaktifkan pemeriksaan HTTPS menggunakan pendekatan yang disajikan di sini :

Saya memasukkan kode berikut ke dalam ISomeServicekelas:

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();
    }
}

Karena saya menggunakan https://AAA.BBB.CCC.DDD:9443/ISomeServiceuntuk tujuan pengujian saja, ini adalah solusi yang cukup baik.

Mentiflectax
sumber
Pendekatan yang disebutkan dalam tautan yang disebutkan di atas tampaknya diblokir ( nakov.com/blog/2009/07/16/… ). Adakah yang bisa memperbarui tautan?
Yohanes
Saya mencoba menonaktifkan validasi melakukan proses ini tetapi validasi browser untuk protokol SSL (kerentanan Poodle) memberi saya: ssl_error_no_cypher_overlap. Ada ide?
Will824
Halo, saya mendapatkan org.springframework.web.client.HttpClientErrorException: 403 Forbidden
73
menonaktifkan pemeriksaan HTTPS bukanlah "solusi". Anda harus mengatakan saya menemukan "tambalan".
Jus12
2
Ini akan menyebabkan kerentanan pada Pre_prod and Production. 1. Buat entri host pada file host windows 2. Atau tambahkan nama IP atau FQDN pada kolom Nama alternatif di sertifikat
Shankar
34

Saya memiliki masalah yang sama dan diselesaikan dengan kode ini. Saya meletakkan kode ini sebelum panggilan pertama ke layanan web saya.

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

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

Sederhana dan berfungsi dengan baik.

Ini sumber aslinya.

juanmhidalgo
sumber
3
Atau Anda bisa mengganti seluruh isi fungsi verifikasi () dengan return hostname.equals("localhost");, jika itu yang ingin Anda lakukan. Ini ifbenar-benar berlebihan.
CVn
Ini adalah perbaikan sederhana dan cepat yang membantu kami menguji di lingkungan pengujian vendor yang tidak memiliki sertifikat yang tepat. Terima kasih banyak!
dacDave
@ JuanM.Hidalgo yang berhasil untuk saya, menempatkan kode di atas tepat sebelum panggilan ke HttpsURLConnection connection = (HttpsURLConnection) obj.openConnection();. Juga, apakah ini mengabaikan setiap sertifikat? Karena saya melihat solusi seperti itu rentan terhadap keamanan. Terima kasih!
ThunderWiring
jawaban ini memecahkan masalah pengecualian sertifikat SSL dan karakter non LDH saya, saya dapat melihat ada bug yang dilaporkan di JDK terbuka, bugs.openjdk.java.net/browse/JDK-8170265
Akhil S Kamath
28

Ini adalah pertanyaan lama, namun saya mengalami masalah yang sama saat berpindah dari JDK 1.8.0_144 ke jdk 1.8.0_191

Kami menemukan petunjuk di changelog:

Changelog

kami menambahkan properti sistem tambahan berikut, yang membantu dalam kasus kami untuk memecahkan masalah ini:

-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true
Markus
sumber
25

Verifikasi identitas sertifikat dilakukan terhadap apa yang diminta klien.

Saat klien Anda menggunakan https://xxx.xxx.xxx.xxx/something( xxx.xxx.xxx.xxxdengan alamat IP), identitas sertifikat diperiksa terhadap alamat IP ini (secara teori, hanya menggunakan ekstensi IP SAN).

Jika sertifikat Anda tidak memiliki IP SAN, tetapi DNS SAN (atau jika tidak ada DNS SAN, Nama Umum di Subjek DN), Anda bisa membuatnya berfungsi dengan membuat klien Anda menggunakan URL dengan nama host itu sebagai gantinya (atau nama host yang sertifikatnya akan valid, jika ada beberapa kemungkinan nilai). Misalnya, jika Anda memiliki nama untuk www.example.com, gunakan https://www.example.com/something.

Tentu saja, Anda memerlukan nama host itu untuk menyelesaikan ke alamat IP itu.

Selain itu, jika ada DNS SAN, CN di Subjek DN akan diabaikan, jadi gunakan nama yang cocok dengan salah satu SAN DNS dalam kasus ini.

Bruno
sumber
1
Saya tidak dapat mengakses layanan melalui http://www.example.com/someservice. Apakah benar bahwa agar sertifikat berfungsi dengan alamat berbasis IP ( https://AAA.BBB.CCC.DDD:9443/ISomeService), saya perlu menyetel semua CNbidang ke AAA.BBB.CCC.DDD(ganti someSubdomain.someorganisation.comdengan AAA.BBB.CCC.DDDdi file di atas) dan mengimpor file sertifikat yang dihasilkan?
Mentiflectax
Anda tidak dapat melakukan apa pun tentang CN atau sertifikat jika Anda tidak mengontrol server.
Bruno
untuk mengakses alamat ip untuk tujuan tes Anda dapat mengubah sementara /etc/hostsfile Anda atau yang setara
tyoc213
1
Dalam kode saya, saya mengirim permintaan ke IP publik, tetapi sertifikat CN adalah nama host. Jadi dalam kode saya, saya mengganti IP dengan nama host, dan mengkonfigurasi / etc / hosts saya untuk mengaitkan nama host ini ke IP. Terpecahkan !
Leopold Gault
15

Untuk mengimpor sertifikat:

  1. Ekstrak sertifikat dari server, misalnya openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txtIni akan mengekstrak sertifikat dalam format PEM.
  2. Ubah sertifikat ke dalam format DER karena inilah yang diharapkan keytool, mis openssl x509 -in certs.txt -out certs.der -outform DER
  3. Sekarang Anda ingin mengimpor sertifikat ini ke file 'cacert' default sistem. Temukan file 'cacerts' default sistem untuk instalasi Java Anda. Lihatlah Bagaimana cara mendapatkan lokasi cacert dari instalasi java default?
  4. Impor sertifikat ke file cacerts itu: sudo keytool -importcert -file certs.der -keystore <path-to-cacerts>Kata sandi cacerts default adalah 'changeit'.

Jika sertifikat dikeluarkan untuk FQDN dan Anda mencoba menghubungkan dengan alamat IP di kode Java Anda, ini mungkin harus diperbaiki dalam kode Anda daripada mengotak-atik sertifikat itu sendiri. Ubah kode Anda untuk terhubung dengan FQDN. Jika FQDN tidak dapat diselesaikan pada mesin dev Anda, cukup tambahkan ke file host Anda, atau konfigurasikan mesin Anda dengan server DNS yang dapat menyelesaikan FQDN ini.

andreycpp
sumber
"Jika FQDN tidak dapat dipecahkan pada mesin dev Anda, cukup tambahkan ke file host Anda" - help. Terima kasih banyak!
Woland
Saya melakukan hal yang sama tetapi tetap saja, masalah tetap ada. Apakah ada hal lain yang bisa dilakukan dengan pendekatan ini?
pkgajulapalli
9

Saya memperbaiki masalah ini dengan cara yang benar dengan menambahkan nama alt subjek dalam sertifikat daripada membuat perubahan apa pun dalam kode atau menonaktifkan SSL tidak seperti jawaban lain yang disarankan di sini. Jika Anda melihat dengan jelas pengecualian mengatakan "Nama alt subjek hilang" jadi cara yang benar adalah menambahkannya

Silakan lihat tautan ini untuk memahami langkah demi langkah .

Kesalahan di atas berarti file JKS Anda tidak memiliki domain yang diperlukan tempat Anda mencoba mengakses aplikasi. Anda harus Menggunakan Open SSL dan alat kunci untuk menambahkan beberapa domain

  1. Salin openssl.cnf ke direktori saat ini
  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/[email protected]' -days 365
  5. Ekspor file kunci publik (.pem) ke format PKS12. Ini akan meminta Anda memasukkan kata sandi

    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. Buat a.JKS dari PEM yang ditandatangani sendiri (Keystore)

    keytool -importkeystore -destkeystore keystore.jks -deststoretype PKCS12 -srcstoretype PKCS12 -srckeystore keystore.p12
  7. Hasilkan Sertifikat dari Keystore atau file JKS di atas

    keytool -export -keystore keystore.jks -alias myalias -file selfsigned.crt
  8. Karena sertifikat di atas adalah Self Signed dan tidak divalidasi oleh CA, maka perlu ditambahkan di Truststore (file Cacerts di lokasi di bawah untuk MAC, untuk Windows, cari tahu di mana JDK Anda diinstal.)

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

Jawaban asli diposting di tautan ini di sini .

Abhishek Galoda
sumber
4

Anda mungkin tidak ingin menonaktifkan semua Verifikasi ssl sehingga Anda dapat menonaktifkan verifikasi hostName melalui ini yang sedikit kurang menakutkan daripada alternatif:

HttpsURLConnection.setDefaultHostnameVerifier(
    SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

[EDIT]

Seperti yang disebutkan oleh conapart3 SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERsekarang sudah tidak digunakan lagi, jadi mungkin akan dihapus di versi yang lebih baru, jadi Anda mungkin akan dipaksa di masa depan untuk menggulung milik Anda sendiri, meskipun saya masih akan mengatakan saya akan menghindari solusi apa pun di mana semua verifikasi dimatikan.

kehidupan yang luar biasa
sumber
2
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERsekarang tidak digunakan lagi.
conapart3
3

Masalah saya dengan mendapatkan kesalahan ini telah diatasi dengan menggunakan URL lengkap "qatest.ourCompany.com/webService" bukan hanya "qatest / webService". Alasannya adalah bahwa sertifikat keamanan kami memiliki karakter pengganti yaitu "* .PerusahaanAnda.com". Setelah saya memasukkan alamat lengkap pengecualiannya hilang. Semoga ini membantu.

Shahriar
sumber
2

Sudah menjawabnya di https://stackoverflow.com/a/53491151/1909708 .

Ini gagal karena nama umum sertifikat ( CNdalam sertifikasi Subject) maupun nama alternatif ( Subject Alternative Namedalam sertifikat) tidak cocok dengan nama host target atau alamat IP.

Misalnya, dari JVM, saat mencoba menyambungkan ke alamat IP ( WW.XX.YY.ZZ) dan bukan nama DNS ( https://stackoverflow.com ), sambungan HTTPS akan gagal karena sertifikat yang disimpan di java truststore cacertsmengharapkan nama umum (atau nama alternatif sertifikat seperti stackexchange.com atau * .stackoverflow.com dll.) agar sesuai dengan alamat target.

Silakan periksa: 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();

Di atas, berikan HostnameVerifierobjek yang diimplementasikan yang selalu mengembalikan true:

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

Untuk Spring Boot RestTemplate:

  • tambahkan org.apache.httpcomponents.httpcoreketergantungan
  • gunakan NoopHostnameVerifieruntuk pabrik SSL:

    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);
Grigory Kislin
sumber
0

Saya mendapat pertanyaan ini setelah mendapat pesan kesalahan yang sama. Namun dalam kasus saya, kami memiliki dua URL dengan subdomain berbeda ( http://example1.xxx.com/someservice dan http://example2.yyy.com/someservice ) yang diarahkan ke server yang sama. Server ini hanya memiliki satu sertifikat karakter pengganti untuk domain * .xxx.com. Saat menggunakan layanan melalui domain kedua, sertifikat yang ditemukan (* .xxx.com) tidak cocok dengan domain yang diminta (* .yyy.com) dan kesalahan terjadi.

Dalam hal ini kita tidak boleh mencoba untuk memperbaiki kesalahan pesan dengan menurunkan keamanan SSL, tetapi harus memeriksa server dan sertifikat di atasnya.

Gert
sumber
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();
            }
        }
    }
}
pengguna11888077
sumber
1
harap tambahkan teks penjelasan ke kode Anda. Lihat stackoverflow.com/help/how-to-answer
jasie
1
Ini adalah cacat keamanan. Ini adalah cara pertama menonaktifkan verifikasi sertifikat. Setiap orang yang menyalin-menempel solusi ini akan membuat bug keamanan di perangkat lunak mereka.
Marek Puchalski
0

Saya telah melalui 2 cara SSL di springboot. Saya telah membuat semua layanan konfigurasi yang benar tomcat server dan pemanggil layanan RestTemplate. tapi saya mendapatkan kesalahan sebagai "java.security.cert.CertificateException: Tidak ada nama alternatif subjek"

Setelah melalui solusi, saya menemukan, JVM membutuhkan sertifikat ini jika tidak maka akan memberikan kesalahan jabat tangan.

Sekarang, bagaimana menambahkan ini ke JVM.

buka file jre / lib / security / cacerts. kita perlu menambahkan file sertifikat server kita ke file cacerts jvm ini.

Perintah untuk menambahkan sertifikat server ke file cacerts melalui baris perintah di windows.

C: \ Program Files \ Java \ jdk1.8.0_191 \ jre \ lib \ security> keytool -import -noprompt -trustcacerts -alias sslserver -file E: \ spring_cloud_sachin \ ssl_keys \ sslserver.cer -keystore cacerts -storepass changeit

Periksa sertifikat server diinstal atau tidak:

C: \ Program Files \ Java \ jdk1.8.0_191 \ jre \ lib \ security> keytool -list -keystore cacerts

Anda dapat melihat daftar sertifikat yang dipasang:

untuk detail lebih lanjut: https://sachin4java.blogspot.com/2019/08/javasecuritycertcertificateexception-no.html

Sachin Rane
sumber
0

tambahkan entri host dengan ip yang sesuai dengan CN di sertifikat

CN = someSubdomain.someorganisation.com

sekarang perbarui ip dengan nama CN tempat Anda mencoba mengakses url.

Itu berhasil untuk saya.

manoj
sumber
0

Kode ini akan bekerja seperti pesona dan menggunakan objek restTemple untuk sisa kode.

  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);
}
Nizam Mahammad
sumber
0

Jika Anda memiliki sertifikat dengan CN dan Nama Alternatif Subjek (SAN), jika Anda membuat permintaan berdasarkan konten CN, konten tertentu tersebut juga harus ada di SAN, jika tidak maka akan gagal dengan kesalahan yang dimaksud.

Dalam kasus saya CN memiliki sesuatu, SAN memiliki sesuatu yang lain. Saya harus menggunakan URL SAN, dan kemudian berfungsi dengan baik.

Tudor
sumber
-3

Tambahkan alamat IP Anda di file hosts. Yang ada di folder C: \ Windows \ System32 \ drivers \ etc. Tambahkan juga IP dan Nama Domain dari alamat IP. contoh: aaa.bbb.ccc.ddd [email protected]

Prakash Soni
sumber
-5

Saya telah menyelesaikan masalah dengan cara berikut.

1. Membuat kelas. Kelas memiliki beberapa implementasi kosong

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. Membuat metode

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. Panggil metode disableSSL () tempat pengecualian dilemparkan. Ini bekerja dengan baik.
Aditya Bhuyan
sumber