Mengabaikan sertifikat SSL di Apache HttpClient 4.3

102

Bagaimana cara mengabaikan sertifikat SSL (percaya semua) untuk Apache HttpClient 4.3 ?

Semua jawaban yang saya temukan di SO memperlakukan versi sebelumnya, dan API berubah.

Terkait:

Edit:

  • Ini hanya untuk tujuan pengujian. Anak-anak, jangan mencobanya di rumah (atau dalam produksi)
Jakub M.
sumber

Jawaban:

146

Kode di bawah ini berfungsi untuk mempercayai sertifikat yang ditandatangani sendiri. Anda harus menggunakan TrustSelfSignedStrategy saat membuat klien Anda:

SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
        sslsf).build();

HttpGet httpGet = new HttpGet("https://some-server");
CloseableHttpResponse response = httpclient.execute(httpGet);
try {
    System.out.println(response.getStatusLine());
    HttpEntity entity = response.getEntity();
    EntityUtils.consume(entity);
} finally {
    response.close();
}

Saya tidak menyertakan dengan SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERsengaja: Intinya adalah untuk mengizinkan pengujian dengan sertifikat yang ditandatangani sendiri sehingga Anda tidak harus memperoleh sertifikat yang sesuai dari otoritas sertifikasi. Anda dapat dengan mudah membuat sertifikat yang ditandatangani sendiri dengan nama host yang benar, jadi lakukan itu alih-alih menambahkan SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERbendera.

mavroprovato.dll
sumber
8
Saya harus menambahkan argumen SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER ke konstruktor untuk mendapatkan ini bekerja dengan HttpClientBuilder (seperti yang disebutkan dalam tanggapan holmis83 terhadap vasekt).
dejuknow
2
Saya juga harus menggunakan ALLOW_ALL_HOSTNAME_VERIFIER: SSLConnectionSocketFactory (builder.build (), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Nama tampilan
Kode ini bekerja untuk saya tanpa menggunakan konstruktor usang dengan argumenSSLConnectionSocketFactory.ALLOW_‌​ALL_HOSTNAME_VERIFIER
user11153
Saya berharap Anda telah menentukan referensi lengkap dari kelas yang Anda gunakan. Beberapa kelas yang disebut SSLContextBuilderditemukan oleh Idea.
MasterMind
91

Jika Anda menggunakan prosedur PoolingHttpClientConnectionManager di atas tidak berfungsi, SSLContext kustom akan diabaikan. Anda harus meneruskan socketFactoryRegistry di contructor saat membuat PoolingHttpClientConnectionManager.

SSLContextBuilder builder = SSLContexts.custom();
builder.loadTrustMaterial(null, new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        return true;
    }
});
SSLContext sslContext = builder.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslContext, new X509HostnameVerifier() {
            @Override
            public void verify(String host, SSLSocket ssl)
                    throws IOException {
            }

            @Override
            public void verify(String host, X509Certificate cert)
                    throws SSLException {
            }

            @Override
            public void verify(String host, String[] cns,
                    String[] subjectAlts) throws SSLException {
            }

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

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

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(
        socketFactoryRegistry);
CloseableHttpClient httpclient = HttpClients.custom()
        .setConnectionManager(cm).build();
vasekt
sumber
11
Daripada membuat X509HostnameVerifier Anda sendiri, Anda dapat menggunakan SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER.
holmis83
Seperti yang ditandai di bawah ini oleh @ rich95, default untuk HttpClients adalah memberi Anda PoolingHttpClient, jadi ini sangat sering relevan. Saya harus mencoba beberapa dari jawaban ini sebelum menemukan bahwa saya membutuhkan ini.
SunSear
1
Mencoba menerapkan ini di WebSphere dan mendapatkan "java.security.KeyStoreException: IBMTrustManager: Masalah mengakses toko kepercayaan java.io.IOException: Format keystore tidak valid" Untuk menghindari, Anda perlu meneruskan KeyStore trustStore = KeyStore.getInstance (KeyStore.getDefaultType ()); bukannya null untuk builder.loadTrustMaterial
Georgy Gobozov
1
Sebenarnya, dengan HttpClient 4.5, keduanya HttpClients.custom().setConnectionManager(cm).build()dan HttpClients.custom().setSSLSocketFactory(connectionFactory).build()akan berfungsi, jadi Anda tidak perlu membuatPoolingHttpClientConnectionManager
soulmachine
Cara menggunakan PoolingHttpClientConnectionManager setelah membuat ini, kode saya berfungsi tetapi saya ingin tahu apakah penggabungan koneksi berfungsi atau tidak
Labeo
34

Sebagai tambahan untuk jawaban @mavroprovato, jika Anda ingin mempercayai semua sertifikat alih-alih hanya ditandatangani sendiri, Anda akan melakukannya (dengan gaya kode Anda)

builder.loadTrustMaterial(null, new TrustStrategy(){
    public boolean isTrusted(X509Certificate[] chain, String authType)
        throws CertificateException {
        return true;
    }
});

atau (salin-tempel langsung dari kode saya sendiri):

import javax.net.ssl.SSLContext;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.ssl.SSLContexts;

// ...

        SSLContext sslContext = SSLContexts
                .custom()
                //FIXME to contain real trust store
                .loadTrustMaterial(new TrustStrategy() {
                    @Override
                    public boolean isTrusted(X509Certificate[] chain,
                        String authType) throws CertificateException {
                        return true;
                    }
                })
                .build();

Dan jika Anda juga ingin melewati verifikasi nama host, Anda perlu menyetelnya

    CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
            sslsf).setSSLHostnameVerifier( NoopHostnameVerifier.INSTANCE).build();

demikian juga. (ALLOW_ALL_HOSTNAME_VERIFIER tidak digunakan lagi).

Peringatan wajib: Anda tidak seharusnya melakukan ini, menerima semua sertifikat adalah hal yang buruk. Namun ada beberapa kasus penggunaan yang jarang terjadi di mana Anda ingin melakukan ini.

Sebagai catatan untuk kode yang diberikan sebelumnya, Anda akan ingin menutup respons meskipun httpclient.execute () melontarkan pengecualian

CloseableHttpResponse response = null;
try {
    response = httpclient.execute(httpGet);
    System.out.println(response.getStatusLine());
    HttpEntity entity = response.getEntity();
    EntityUtils.consume(entity);
}
finally {
    if (response != null) {
        response.close();
    }
}

Kode di atas telah diuji menggunakan

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>

Dan bagi yang tertarik, inilah set pengujian lengkap saya:

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLPeerUnverifiedException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class TrustAllCertificatesTest {
    final String expiredCertSite = "https://expired.badssl.com/";
    final String selfSignedCertSite = "https://self-signed.badssl.com/";
    final String wrongHostCertSite = "https://wrong.host.badssl.com/";

    static final TrustStrategy trustSelfSignedStrategy = new TrustSelfSignedStrategy();
    static final TrustStrategy trustAllStrategy = new TrustStrategy(){
        public boolean isTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            return true;
        }
    };

    @Test
    public void testSelfSignedOnSelfSignedUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustSelfSignedStrategy);
    }
    @Test(expected = SSLHandshakeException.class)
    public void testExpiredOnSelfSignedUsingCode() throws Exception {
        doGet(expiredCertSite, trustSelfSignedStrategy);
    }
    @Test(expected = SSLPeerUnverifiedException.class)
    public void testWrongHostOnSelfSignedUsingCode() throws Exception {
        doGet(wrongHostCertSite, trustSelfSignedStrategy);
    }

    @Test
    public void testSelfSignedOnTrustAllUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustAllStrategy);
    }
    @Test
    public void testExpiredOnTrustAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy);
    }
    @Test(expected = SSLPeerUnverifiedException.class)
    public void testWrongHostOnTrustAllUsingCode() throws Exception {
        doGet(wrongHostCertSite, trustAllStrategy);
    }

    @Test
    public void testSelfSignedOnAllowAllUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }
    @Test
    public void testExpiredOnAllowAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }
    @Test
    public void testWrongHostOnAllowAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }

    public void doGet(String url, TrustStrategy trustStrategy, HostnameVerifier hostnameVerifier) throws Exception {
        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(trustStrategy);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
                sslsf).setSSLHostnameVerifier(hostnameVerifier).build();

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpclient.execute(httpGet);
        try {
            System.out.println(response.getStatusLine());
            HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    }
    public void doGet(String url, TrustStrategy trustStrategy) throws Exception {

        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(trustStrategy);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
                sslsf).build();

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpclient.execute(httpGet);
        try {
            System.out.println(response.getStatusLine());
            HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    }
}

(proyek uji kerja di github )

eis
sumber
1
HttpClient # execution tidak akan pernah mengembalikan objek respons null jika ada pengecualian. Selain itu, implementasi HttpClient stok akan memastikan deallokasi otomatis semua sumber daya sistem seperti koneksi yang disewakan jika terjadi pengecualian selama eksekusi permintaan. Penanganan pengecualian yang digunakan oleh mavroprovato sangat memadai.
ok2c
@oleg, titik antarmuka Closable adalah "Tutup aliran [...] dan lepaskan sumber daya sistem apa pun yang terkait dengannya. Jika aliran sudah ditutup, pemanggilan metode ini tidak akan berpengaruh." jadi praktik terbaik adalah menggunakannya bahkan jika tidak diperlukan. Juga, saya tidak mengerti komentar mengembalikan tanggapan nol - tentu saja tidak, jika itu membuat pengecualian, itu tidak mengembalikan apa pun?
eis
1
Apache HttpClient tidak pernah mengembalikan objek respons nol atau yang diinisialisasi sebagian. Ini tidak ada hubungannya dengan berapa kali #close dipanggil, melainkan pemeriksaan null yang sama sekali tidak perlu di klausa terakhir
ok2c
@oleg dan tidak pernah melakukan kode yang saya berikan menganggap itu akan mengembalikan null atau objek respons yang diinisialisasi sebagian, atau bahkan memeriksa kasus seperti itu. Saya tidak tahu apa yang Anda bicarakan?
eis
1
[ menghela napas ] yang sama sekali tidak perlu mengingat bahwa HttpResponse tidak pernah bisa nol dan dalam kasus pengecualian, metode #execute akan berhenti tanpa mengembalikan respons ;-)
ok2c
22

Satu tambahan kecil untuk jawaban vasekt:

Solusi yang disediakan dengan SocketFactoryRegistry berfungsi saat menggunakan PoolingHttpClientConnectionManager.

Namun, koneksi melalui http biasa tidak berfungsi lagi. Anda harus menambahkan PlainConnectionSocketFactory untuk protokol http tambahan untuk membuatnya berfungsi kembali:

Registry<ConnectionSocketFactory> socketFactoryRegistry = 
  RegistryBuilder.<ConnectionSocketFactory> create()
  .register("https", sslsf)
  .register("http", new PlainConnectionSocketFactory()).build();
migo
sumber
Saya yakin httpprotokol digunakan PlainConnectionSocketFactory secara default. Saya hanya mendaftar httpsdan httpclientmasih bisa mendapatkan URL HTTP biasa. jadi menurut saya langkah ini tidak perlu.
Soulmachine
@soulmachine itu tidak akan untukPoolingHttpClientConnectionManager
amseager
15

Setelah mencoba berbagai opsi, konfigurasi berikut berfungsi untuk http dan https

        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(),SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);


        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", new PlainConnectionSocketFactory())
                .register("https", sslsf)
                .build();


        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
        cm.setMaxTotal(2000);//max connection


        //System.setProperty("jsse.enableSNIExtension", "false"); //""
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .setConnectionManager(cm)
                .build();

Saya menggunakan http-client 4.3.3 -

compile 'org.apache.httpcomponents:httpclient:4.3.3'

Saurabh
sumber
1
Terima kasih telah memberikan contoh yang lengkap dan berfungsi sepenuhnya! Saya mengalami banyak masalah dengan solusi sebelumnya dan ini sangat membantu. Juga membantu Anda memberikan pernyataan import, karena ada beberapa kelas dengan nama yang sama, yang menambah kebingungan.
helmy
8

Kode kerja yang lebih sederhana dan lebih pendek:

Kami menggunakan HTTPClient 4.3.5 dan kami mencoba hampir semua solusi yang ada di stackoverflow tetapi tidak ada, Setelah memikirkan dan mencari tahu masalah, kami menemukan kode berikut yang berfungsi dengan sempurna, cukup tambahkan sebelum membuat instance HttpClient.

beberapa metode yang Anda gunakan untuk membuat permintaan posting ...

SSLContextBuilder builder = new SSLContextBuilder();
    builder.loadTrustMaterial(null, new TrustStrategy() {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            return true;
        }
    });

    SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(builder.build(),
            SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSF).build();
    HttpPost postRequest = new HttpPost(url);

terus menelepon dan menggunakan contoh HttpPost dalam bentuk normal

Anggota parlemen Hamed
sumber
Bagaimana kita bisa memposting Data di header? Jika ya, lihat Permintaan Buruk HTTP / 1.1 400
6

Berikut adalah penyulingan yang berfungsi dari teknik di atas, setara dengan "curl --insecure":

HttpClient getInsecureHttpClient() throws GeneralSecurityException {
    TrustStrategy trustStrategy = new TrustStrategy() {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) {
            return true;
        }
    };

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

    return HttpClients.custom()
            .setSSLSocketFactory(new SSLConnectionSocketFactory(
                    new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(),
                    hostnameVerifier))
            .build();
}
divbyzero.dll
sumber
5

Saat menggunakan http client 4.5 saya harus menggunakan javasx.net.ssl.HostnameVerifier untuk mengizinkan nama host (untuk tujuan pengujian). Inilah yang akhirnya saya lakukan:

CloseableHttpClient httpClient = null;
    try {
        SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
        sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());

        HostnameVerifier hostnameVerifierAllowAll = new HostnameVerifier() 
            {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };

        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);

        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
            new AuthScope("192.168.30.34", 8443),
            new UsernamePasswordCredentials("root", "password"));

        httpClient = HttpClients.custom()
            .setSSLSocketFactory(sslSocketFactory)
            .setDefaultCredentialsProvider(credsProvider)
            .build();

        HttpGet httpGet = new HttpGet("https://192.168.30.34:8443/axis/services/getStuff?firstResult=0&maxResults=1000");

        CloseableHttpResponse response = httpClient.execute(httpGet);

        int httpStatus = response.getStatusLine().getStatusCode();
        if (httpStatus >= 200 && httpStatus < 300) { [...]
        } else {
            throw new ClientProtocolException("Unexpected response status: " + httpStatus);
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    }
    finally {
        try {
            httpClient.close();
        } catch (IOException ex) {
            logger.error("Error while closing the HTTP client: ", ex);
        }
    }
Kurt
sumber
Penerapan HostnameVerifier memecahkan masalah untuk HTTPClient 4.5.
digz6666
bagi yang suka lambda (JDK1.8), bisa ganti SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);dengan SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);. Ini menghindari kelas anonim dan membuat kode sedikit lebih mudah dibaca.
Vielinko
3

Di atas PoolingHttpClientConnectionManagerbersama dengan Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build(); Jika Anda ingin httpclient asynchronous menggunakan PoolingNHttpClientConnectionManagerkode harus mirip dengan berikut

SSLContextBuilder builder = SSLContexts.custom();
builder.loadTrustMaterial(null, new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        return true;
    }
});
SSLContext sslContext = builder.build();
SchemeIOSessionStrategy sslioSessionStrategy = new SSLIOSessionStrategy(sslContext, 
                new HostnameVerifier(){
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;// TODO as of now allow all hostnames
            }
        });
Registry<SchemeIOSessionStrategy> sslioSessionRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create().register("https", sslioSessionStrategy).build();
PoolingNHttpClientConnectionManager ncm  = new PoolingNHttpClientConnectionManager(new DefaultConnectingIOReactor(),sslioSessionRegistry);
CloseableHttpAsyncClient asyncHttpClient = HttpAsyncClients.custom().setConnectionManager(ncm).build();
asyncHttpClient.start();        
Anant Laxmikant Bobde
sumber
3

Jika Anda menggunakan HttpClient 4.5.x, kode Anda bisa serupa dengan berikut ini:

SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
        TrustSelfSignedStrategy.INSTANCE).build();
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
        sslContext, NoopHostnameVerifier.INSTANCE);

HttpClient httpClient = HttpClients.custom()
                                   .setDefaultCookieStore(new BasicCookieStore())
                                   .setSSLSocketFactory(sslSocketFactory)
                                   .build();
Paul Vargas
sumber
Tidak berhasil untuk saya. Saya menggunakan HttpClient: 4.5.5. dan HttpCore 4.4.9
Vijay Kumar
2
class ApacheHttpClient {

    /***
     * This is a https get request that bypasses certificate checking and hostname verifier.
     * It uses basis authentication method.
     * It is tested with Apache httpclient-4.4.
     * It dumps the contents of a https page on the console output.
     * It is very similar to http get request, but with the additional customization of
     *   - credential provider, and
     *   - SSLConnectionSocketFactory to bypass certification checking and hostname verifier.
     * @param path String
     * @param username String
     * @param password String
     * @throws IOException
     */
    public void get(String path, String username, String password) throws IOException {
        final CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCredentialsProvider(createCredsProvider(username, password))
                .setSSLSocketFactory(createGenerousSSLSocketFactory())
                .build();

        final CloseableHttpResponse response = httpClient.execute(new HttpGet(path));
        try {
            HttpEntity entity = response.getEntity();
            if (entity == null)
                return;
            System.out.println(EntityUtils.toString(entity));
        } finally {
            response.close();
            httpClient.close();
        }
    }

    private CredentialsProvider createCredsProvider(String username, String password) {
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));
        return credsProvider;
    }

    /***
     * 
     * @return SSLConnectionSocketFactory that bypass certificate check and bypass HostnameVerifier
     */
    private SSLConnectionSocketFactory createGenerousSSLSocketFactory() {
        SSLContext sslContext;
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[]{createGenerousTrustManager()}, new SecureRandom());
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
        return new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    }

    private X509TrustManager createGenerousTrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] cert, String s) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] cert, String s) throws CertificateException {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
    }
}
Dahai Li
sumber
2

Percayai Semua Sertifikat di Klien HTTP Apache

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

          try {
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                        sc);
                httpclient = HttpClients.custom().setSSLSocketFactory(
                        sslsf).build();
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
Jeff Z
sumber
Ini bekerja dengan baik dengan httpclient 4.5.9, Cukup salin dan tempel seluruh konten itu saja.
sathya
1

(Saya akan menambahkan komentar langsung ke jawaban vasekt tetapi saya tidak memiliki cukup poin reputasi (tidak yakin logikanya di sana)

Bagaimanapun ... yang ingin saya katakan adalah bahwa meskipun Anda tidak secara eksplisit membuat / meminta PoolingConnection, tidak berarti Anda tidak mendapatkannya.

Saya menjadi gila mencoba mencari tahu mengapa solusi asli tidak berhasil untuk saya, tetapi saya mengabaikan jawaban vasekt karena "tidak berlaku untuk kasus saya" - salah!

Saya sedang menatap jejak tumpukan saya ketika rendah dan lihatlah saya melihat Sambungan Pooling di tengahnya. Bang - Aku lelah dengan penambahan dan kesuksesannya !! (demo kami besok dan saya semakin putus asa) :-)

rich95
sumber
0

Anda dapat menggunakan potongan kode berikut untuk mendapatkan contoh HttpClient tanpa pemeriksaan sertifikasi ssl.

private HttpClient getSSLHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {

        LogLoader.serverLog.trace("In getSSLHttpClient()");

        SSLContext context = SSLContext.getInstance("SSL");

        TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        context.init(null, new TrustManager[] { tm }, null);

        HttpClientBuilder builder = HttpClientBuilder.create();
        SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(context);
        builder.setSSLSocketFactory(sslConnectionFactory);

        PlainConnectionSocketFactory plainConnectionSocketFactory = new PlainConnectionSocketFactory();
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("https", sslConnectionFactory).register("http", plainConnectionSocketFactory).build();

        PoolingHttpClientConnectionManager ccm = new PoolingHttpClientConnectionManager(registry);
        ccm.setMaxTotal(BaseConstant.CONNECTION_POOL_SIZE);
        ccm.setDefaultMaxPerRoute(BaseConstant.CONNECTION_POOL_SIZE);
        builder.setConnectionManager((HttpClientConnectionManager) ccm);

        builder.disableRedirectHandling();

        LogLoader.serverLog.trace("Out getSSLHttpClient()");

        return builder.build();
    }
Radadiya Nikunj
sumber
0

Sedikit tweak untuk menjawab dari @divbyzero di atas untuk memperbaiki peringatan keamanan sonar

CloseableHttpClient getInsecureHttpClient() throws GeneralSecurityException {
            TrustStrategy trustStrategy = (chain, authType) -> true;

            HostnameVerifier hostnameVerifier = (hostname, session) -> hostname.equalsIgnoreCase(session.getPeerHost());

            return HttpClients.custom()
                    .setSSLSocketFactory(new SSLConnectionSocketFactory(new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(), hostnameVerifier))
                    .build();
        }
andyd
sumber
0

Awalnya, saya dapat menonaktifkan untuk localhost menggunakan strategi kepercayaan, kemudian saya menambahkan NoopHostnameVerifier. Sekarang ini akan berfungsi untuk localhost dan nama mesin apa pun

SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(null, new TrustStrategy() {

            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }

        }).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext, NoopHostnameVerifier.INSTANCE);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
U_R_Naveen UR_Naveen
sumber