Perlu dicatat bahwa jawaban untuk pertanyaan ini tidak melakukan lebih dari yang diminta: mereka membiarkan Anda mengabaikan kesalahan tetapi tidak memperbaiki masalah mendasar (sedikit seperti melepas baterai dari alarm asap daripada memadamkan api ). Sertifikat memiliki tujuan untuk memastikan keamanan koneksi SSL / TLS, mengabaikan kesalahan yang menyebabkan kerentanan terhadap serangan MITM. Gunakan sertifikat uji alih-alih mengabaikan kesalahan.
"seperti melepas baterai dari alarm asap" Anda mungkin memberi pengembang lain manfaat dari keraguan dan menganggap mereka tahu apa yang mereka lakukan. Mungkin motivasi untuk pertanyaan ini adalah pengujian lokal dan OP ingin menjalankan tes cepat tanpa melalui jumlah Java boilerplate yang diperlukan untuk mengatur bahkan lingkungan SSL sederhana. Mungkin seseorang bisa saja menjawab pertanyaan tanpa pergi ke kuliah "lebih suci dari kamu".
Mike
Yaitu di server JIRA internal perusahaan kami memiliki beberapa "sertifikat berbasis kebijakan keamanan windows" yang berlaku pada mesin Windows yang termasuk dalam domain dan tidak berlaku pada yang lain. Saya tidak bisa mengendalikan kebijakan ini dan masih ingin menelepon JIRA REST API.
odiszapc
1
@ Bruno Ketidakmampuan untuk menonaktifkan detektor asap untuk jangka waktu 30-60 menit saat berurusan dengan api dapur kecil menunjukkan kurangnya wawasan tentang pola penggunaan oleh beberapa pejabat hukum di beberapa titik yang saya merasa berbatasan dengan kriminal. Fakta bahwa ada konsep "mengeluarkan baterai dari alarm asap" membuktikan hal ini. Saya merasakan tingkat kemarahan yang sama karena harus mendapatkan sertifikat untuk bekerja untuk tes sederhana yang saya tahu tidak memiliki konsekuensi keamanan. Keberadaan pertanyaan ini membuktikan hal ini.
Bill K
Jawaban:
84
Anda perlu membuat konteks SSLC dengan TrustManager Anda sendiri dan membuat skema HTTPS menggunakan konteks ini. Ini kodenya,
SSLContext sslContext =SSLContext.getInstance("SSL");// set up a TrustManager that trusts everything
sslContext.init(null,newTrustManager[]{new X509TrustManager(){public X509Certificate[] getAcceptedIssuers(){System.out.println("getAcceptedIssuers =============");returnnull;}publicvoid checkClientTrusted(X509Certificate[] certs,String authType){System.out.println("checkClientTrusted =============");}publicvoid checkServerTrusted(X509Certificate[] certs,String authType){System.out.println("checkServerTrusted =============");}}},newSecureRandom());SSLSocketFactory sf =newSSLSocketFactory(sslContext);Scheme httpsScheme =newScheme("https",443, sf);SchemeRegistry schemeRegistry =newSchemeRegistry();
schemeRegistry.register(httpsScheme);// apache HttpClient version >4.2 should use BasicClientConnectionManagerClientConnectionManager cm =newSingleClientConnManager(schemeRegistry);HttpClient httpClient =newDefaultHttpClient(cm);
Katakanlah saya tidak ingin membeli sertifikat SSL yang valid untuk situs saya dan hanya ingin menggunakannya, kode ini dapat membantu? Kenapa saya tidak melihat bagian di mana URL dibutuhkan atau penanganan pengecualian diperlukan?
Viet
19
Hmm, ia memberi tahu saya bahwa 'SSLSocketFactory baru (ssslCont)' mengharapkan KeyStore, bukan SSLContext. Apakah saya melewatkan sesuatu?
MSpeed
2
Saya mendapatkan kesalahan bahwa X509TrustManager tidak dapat dilemparkan ke TrustManager.
MW.
2
Pastikan Anda mengimpor paket yang benar, yaitu dari org.apache.http.
Sipir
2
Adakah yang tahu cara melempar semua ini menggunakan HttpClientBuilder?
Ali
112
Semua jawaban lain sudah usang atau tidak berfungsi untuk HttpClient 4.3.
Berikut adalah cara untuk mengizinkan semua nama host saat membuat klien http.
Terima kasih atas jawabannya, saya ingin tahu dari paket mana HttpsClients seperti yang saya gunakan dalam kompilasi Android ("org.apache.httpcomponents: httpclient: 4.3.4") tetapi kelas ini tidak muncul.
Juan Saravia
1
Paketnya adalah org.apache.http.impl.client.HttpClients.
erversteeg
14
Ini berfungsi di sekitar ketidakcocokan nama host (saya berasumsi), tetapi tampaknya tidak berfungsi ketika sertifikat tidak ditandatangani oleh otoritas tepercaya.
twm
1
@ twm itu sebabnya ia mengatakan "memungkinkan semua nama host", masalah kepercayaan memerlukan konfigurasi yang berbeda.
eis
1
@ ya, saya menunjukkan bahwa jawaban ini membahas pertanyaan awal dalam beberapa kasus tetapi tidak pada yang lain.
twm
43
Hanya harus melakukan ini dengan HttpClient 4.5 yang lebih baru dan sepertinya mereka sudah mencabut beberapa hal sejak 4.4 jadi inilah cuplikan yang berfungsi untuk saya dan menggunakan API terbaru:
Terima kasih! Ubah saja TrustAllStrategy.INSTANCEdengan TrustSelfSignedStrategy.INSTANCEjawaban ini.
Percy Vega
Ini tidak berhasil untuk saya. javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: gagal membangun jalur PKIX: sun.security. provider.certpath.SunCertPathBuilderException: tidak dapat menemukan jalur sertifikasi yang valid ke target yang diminta
ggb667
26
Sebagai catatan, diuji dengan httpclient 4.3.6 dan kompatibel dengan Pelaksana api fasih:
Untuk HttpClient 4.4 ke atas, Anda harus melakukan ini - dan mungkin juga perlu membuat SSLConnectionSocketFactorymenggunakan itu SSLContext, dan mendefinisikan ini dalam Registry<ConnectionSocketFactory>, jika Anda akan membuat PoolingHttpClientConnectionManager. Jawaban lain lebih populer, tetapi tidak berfungsi di HttpClient 4.4.
Thomas W
1
Bekerja persis seperti ini dengan httpclient-4.3.5.jar.
Harald
18
Untuk Apache HttpClient 4.4:
HttpClientBuilder b =HttpClientBuilder.create();SSLContext sslContext =newSSLContextBuilder().loadTrustMaterial(null,newTrustStrategy(){publicboolean isTrusted(X509Certificate[] arg0,String arg1)throwsCertificateException{returntrue;}}).build();
b.setSslcontext( sslContext);// or SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weakenHostnameVerifier hostnameVerifier =SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;SSLConnectionSocketFactory sslSocketFactory =newSSLConnectionSocketFactory(sslContext, hostnameVerifier);Registry<ConnectionSocketFactory> socketFactoryRegistry =RegistryBuilder.<ConnectionSocketFactory>create().register("http",PlainConnectionSocketFactory.getSocketFactory()).register("https", sslSocketFactory).build();// allows multi-threaded usePoolingHttpClientConnectionManager connMgr =newPoolingHttpClientConnectionManager( socketFactoryRegistry);
b.setConnectionManager( connMgr);HttpClient client = b.build();
Ini diambil dari implementasi kerja kami yang sebenarnya.
Jawaban lain populer, tetapi untuk HttpClient 4.4 mereka tidak berfungsi. Saya menghabiskan berjam-jam mencoba & melelahkan kemungkinan, tetapi tampaknya ada perubahan API sangat besar & relokasi di 4.4.
Metode sf.setHostnameVerifier telah ditinggalkan pada 4.1. Alternatifnya adalah menggunakan salah satu konstruktor. Misalnya:SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
kaliatech
Ini sangat berguna ketika saya harus berurusan dengan kode warisan.
DuncanSungWKim
9
Kami menggunakan HTTPClient 4.3.5 dan kami mencoba hampir semua solusi yang ada di stackoverflow tetapi tidak ada, Setelah berpikir dan mencari tahu masalahnya, kami sampai pada kode berikut yang bekerja dengan sempurna, tambahkan saja sebelum membuat contoh HttpClient.
beberapa metode untuk menelepon ketika membuat permintaan posting ....
Anda dapat mencapai hal yang sama dengan hanya melakukansf.setHostnameVerifier(new AllowAllHostnameVerifier());
Dan Dyer
7
Sf.setHostnameVerifier telah ditinggalkan pada 4.1. Alternatifnya adalah menggunakan salah satu konstruktor. Misalnya:SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
kaliatech
4
DefaultHttpClient httpclient =newDefaultHttpClient();SSLContext sslContext;try{
sslContext =SSLContext.getInstance("SSL");// set up a TrustManager that trusts everythingtry{
sslContext.init(null,newTrustManager[]{new X509TrustManager(){public X509Certificate[] getAcceptedIssuers(){
log.debug("getAcceptedIssuers =============");returnnull;}publicvoid checkClientTrusted(
X509Certificate[] certs,String authType){
log.debug("checkClientTrusted =============");}publicvoid checkServerTrusted(
X509Certificate[] certs,String authType){
log.debug("checkServerTrusted =============");}}},newSecureRandom());}catch(KeyManagementException e){}SSLSocketFactory ssf =newSSLSocketFactory(sslContext,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);ClientConnectionManager ccm =this.httpclient.getConnectionManager();SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(newScheme("https",443, ssf));}catch(Exception e){
log.error(e.getMessage(),e);}
Saya mendapatkan ini: Disebabkan oleh: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Tidak ada nama alternatif subjek yang hadir?
Bagaimana cara mengizinkan koneksi ke situs SSL tanpa sertifikat di HttpClient API atau di RestClient API?
4
Diuji dengan HttpClient 4.5.5 dengan Fluent API
finalSSLContext sslContext =newSSLContextBuilder().loadTrustMaterial(null,(x509CertChain, authType)->true).build();CloseableHttpClient httpClient =HttpClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslContext).build();String result =Executor.newInstance(httpClient).execute(Request.Get("https://localhost:8080/someapi").connectTimeout(1000).socketTimeout(1000)).returnContent().asString();
terima kasih atas jawaban yang diperbarui, saya menghadiahkan hadiah kepada orang baru itu untuk "menyambut" tetapi saya hanya ingin jawaban yang diperbarui untuk semua orang!
1
@ merasa diterima, tentu saja. Saya telah mengangkatnya juga :-)
Tarun Lalwani
2
versi lengkap untuk Apache HttpClient 4.1.3 (berdasarkan kode oleg di atas, tetapi masih membutuhkan allow_all_hostname_verifier di sistem saya):
Jika Anda mengalami masalah ini saat menggunakan AmazonS3Client, yang menyematkan Apache HttpClient 4.1, Anda hanya perlu mendefinisikan properti sistem seperti ini sehingga pemeriksa sertifikat SSL santai:
Jika Anda menggunakan Apache httpClient 4.5.x maka coba ini:
publicstaticvoid main(String... args){try(CloseableHttpClient httpclient = createAcceptSelfSignedCertificateClient()){HttpGet httpget =newHttpGet("https://example.com");System.out.println("Executing request "+ httpget.getRequestLine());
httpclient.execute(httpget);System.out.println("----------------------------------------");}catch(NoSuchAlgorithmException|KeyStoreException|KeyManagementException|IOException e){thrownewRuntimeException(e);}}privatestaticCloseableHttpClient createAcceptSelfSignedCertificateClient()throwsKeyManagementException,NoSuchAlgorithmException,KeyStoreException{// use the TrustSelfSignedStrategy to allow Self Signed CertificatesSSLContext sslContext =SSLContextBuilder.create().loadTrustMaterial(newTrustSelfSignedStrategy()).build();// we can optionally disable hostname verification. // if you don't want to further weaken the security, you don't have to include this.HostnameVerifier allowAllHosts =newNoopHostnameVerifier();// create an SSL Socket Factory to use the SSLContext with the trust self signed certificate strategy// and allow all hosts verifier.SSLConnectionSocketFactory connectionFactory =newSSLConnectionSocketFactory(sslContext, allowAllHosts);// finally create the HttpClient using HttpClient factory methods and assign the ssl socket factoryreturnHttpClients.custom().setSSLSocketFactory(connectionFactory).build();}
Jawaban:
Anda perlu membuat konteks SSLC dengan TrustManager Anda sendiri dan membuat skema HTTPS menggunakan konteks ini. Ini kodenya,
sumber
HttpClientBuilder
?Semua jawaban lain sudah usang atau tidak berfungsi untuk HttpClient 4.3.
Berikut adalah cara untuk mengizinkan semua nama host saat membuat klien http.
Atau jika Anda menggunakan versi 4.4 atau lebih baru, panggilan yang diperbarui terlihat seperti ini:
sumber
Hanya harus melakukan ini dengan HttpClient 4.5 yang lebih baru dan sepertinya mereka sudah mencabut beberapa hal sejak 4.4 jadi inilah cuplikan yang berfungsi untuk saya dan menggunakan API terbaru:
sumber
Sebagai catatan, ada cara yang lebih sederhana untuk mencapai hal yang sama dengan HttpClient 4.1
sumber
new SSLSocketFactory((chain, authType) -> true);
Apache HttpClient 4.5.5
Tidak ada API usang yang digunakan.
Kasus uji sederhana yang dapat diverifikasi:
sumber
TrustAllStrategy.INSTANCE
denganTrustSelfSignedStrategy.INSTANCE
jawaban ini.Sebagai catatan, diuji dengan httpclient 4.3.6 dan kompatibel dengan Pelaksana api fasih:
sumber
SSLConnectionSocketFactory
menggunakan ituSSLContext
, dan mendefinisikan ini dalamRegistry<ConnectionSocketFactory>
, jika Anda akan membuatPoolingHttpClientConnectionManager
. Jawaban lain lebih populer, tetapi tidak berfungsi di HttpClient 4.4.Untuk Apache HttpClient 4.4:
Ini diambil dari implementasi kerja kami yang sebenarnya.
Jawaban lain populer, tetapi untuk HttpClient 4.4 mereka tidak berfungsi. Saya menghabiskan berjam-jam mencoba & melelahkan kemungkinan, tetapi tampaknya ada perubahan API sangat besar & relokasi di 4.4.
Lihat juga penjelasan yang sedikit lebih lengkap di: http://literatejava.com/networks/ignore-ssl-certificate-errors-apache-httpclient-4-4/
Semoga itu bisa membantu!
sumber
Jika semua yang ingin Anda lakukan adalah menyingkirkan kesalahan hostname yang tidak valid, Anda bisa melakukan:
sumber
SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Kami menggunakan HTTPClient 4.3.5 dan kami mencoba hampir semua solusi yang ada di stackoverflow tetapi tidak ada, Setelah berpikir dan mencari tahu masalahnya, kami sampai pada kode berikut yang bekerja dengan sempurna, tambahkan saja sebelum membuat contoh HttpClient.
sumber
Dengan fasih 4.5.2 saya harus membuat modifikasi berikut untuk membuatnya berfungsi.
sumber
Ini adalah bagaimana saya melakukannya -
Menginisialisasi DefaultHTTPClient -
Pabrik SSL Mock -
Jika di belakang proxy, perlu melakukan ini -
sumber
Sebagai tambahan untuk jawaban ZZ Coder, akan lebih baik jika mengganti hostnameverifier.
sumber
sf.setHostnameVerifier(new AllowAllHostnameVerifier());
SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
sumber
Untuk menerima semua sertifikat di HttpClient 4.4.x Anda dapat menggunakan liner berikut saat membuat httpClient:
sumber
Diuji dengan HttpClient 4.5.5 dengan Fluent API
sumber
Kode di bawah ini berfungsi dengan
4.5.5
Output dari kode adalah
Output pada browser adalah
Pom yang digunakan di bawah ini
sumber
versi lengkap untuk Apache HttpClient 4.1.3 (berdasarkan kode oleg di atas, tetapi masih membutuhkan allow_all_hostname_verifier di sistem saya):
Catatan saya melemparkan kembali semua pengecualian karena sungguh, tidak banyak yang bisa saya lakukan jika semua ini gagal dalam sistem nyata!
sumber
Jika Anda menggunakan API yang lancar , Anda harus mengaturnya melalui
Executor
:... di mana
sslContext
konteks SSLC dibuat seperti yang ditunjukkan dalam jawaban ZZ Coder .Setelah itu, Anda dapat melakukan permintaan http Anda sebagai:
Catatan: diuji dengan HttpClient 4.2
sumber
Diuji dengan 4.3.3
}
sumber
Diuji pada 4.5.4:
sumber
Jika Anda mengalami masalah ini saat menggunakan AmazonS3Client, yang menyematkan Apache HttpClient 4.1, Anda hanya perlu mendefinisikan properti sistem seperti ini sehingga pemeriksa sertifikat SSL santai:
-Dcom.amazonaws.sdk.disableCertChecking = true
Mischief berhasil
sumber
fwiw, contoh menggunakan implementasi "RestEasy" dari JAX-RS 2.x untuk membangun klien "kepercayaan semua" khusus ...
dependensi Maven terkait
sumber
Jika Anda menggunakan Apache httpClient 4.5.x maka coba ini:
sumber