অ্যাপাচি এইচটিপিএলপ্লায়েন্টে এসএসএল শংসাপত্র উপেক্ষা 4.3


102

অ্যাপাচি এইচটিটিপিপ্লায়েন্ট 4.3 এর জন্য কীভাবে এসএসএল শংসাপত্র (সকলের বিশ্বাস) উপেক্ষা করবেন ?

এসওতে আমি যে সমস্ত উত্তর পেয়েছি সেগুলি পূর্ববর্তী সংস্করণগুলির চিকিত্সা করে এবং এপিআই বদলে যায়।

সম্পর্কিত:

সম্পাদনা:

  • এটি কেবল পরীক্ষার উদ্দেশ্যে। বাচ্চারা, বাড়িতে এটি চেষ্টা করবেন না (বা উত্পাদনে)

উত্তর:


146

নীচের কোডটি স্ব-স্বাক্ষরিত শংসাপত্রগুলিকে বিশ্বাস করার জন্য কাজ করে। আপনার ক্লায়েন্ট তৈরি করার সময় আপনাকে ট্রাস্টসেলফাইনস্টাইনস্ট্রেজি ব্যবহার করতে হবে :

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

আমি SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERউদ্দেশ্যটি অন্তর্ভুক্ত করিনি : মূল বিষয়টি স্ব স্ব স্বাক্ষরযুক্ত শংসাপত্রগুলির সাথে পরীক্ষার অনুমতি দেওয়ার জন্য যাতে আপনাকে কোনও শংসাপত্র কর্তৃপক্ষের কাছ থেকে কোনও সঠিক শংসাপত্র গ্রহণ করতে হয় না। আপনি সঠিক হোস্টের নাম সহ সহজেই স্ব-স্বাক্ষরিত শংসাপত্র তৈরি করতে পারেন, তাই SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERপতাকা যুক্ত করার পরিবর্তে এটি করুন ।


8
আমাকে এইচটিপিপ্লাইয়েন্টবিল্ডারের সাথে কাজ করার জন্য কনট্রাক্টরের সাথে এসএসএল সংযোগসকেটফ্যাক্ট্রি। ALLOW_ALL_HOSTNAME_VERIFIER যুক্তি যুক্ত করতে হয়েছিল (যেমন ভ্যাসেকটে holmis83 এর প্রতিক্রিয়াতে উল্লিখিত হয়েছে)।
dejuknav

এছাড়াও httpclient সাইটে উদাহরণ পড়ুন hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/...
arajashe

2
আমাকে ALLOW_ALL_HOSTNAME_VERIFIER: এসএসএল সংযোগসকেটফ্যাক্টরি (বিল্ডার.বিল্ড (), এসএসএল সংযোগসকেট ফ্যাক্টরিও ব্যবহার করতে হয়েছে; ALLOW_ALL_HOSTNAME_VERIFIER);
নাম প্রদর্শন করুন

এই কোডটি যুক্তিযুক্ত SSLConnectionSocketFactory.ALLOW_‌​ALL_HOSTNAME_VERIFIER
অবহিত কনস্ট্রাক্টর

আমি আশা করি আপনি যে ক্লাসটি ব্যবহার করছিলেন তার পুরো রেফারেন্স নির্দিষ্ট করে দিয়েছিলেন। একাধিক ক্লাস নামে পরিচিত SSLContextBuilderআইডিয়া খুঁজে পাওয়া যায়।
মাস্টারমাইন্ড

91

যদি আপনি উপরের পুলিংএইচটিপিপিলেটস্লিঙ্কেশন ম্যানেজার পদ্ধতি ব্যবহার করেন না তবে কাস্টম এসএসএল কনটেক্সটকে উপেক্ষা করা হবে। পুলিংএইচটিপিপিলেট ক্লিনিকেশন ম্যানেজার তৈরি করার সময় আপনাকে কনট্রাক্টরে সকেটফ্যাক্টরিআগ্রিজি পাস করতে হবে।

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

11
আপনার নিজস্ব X509 হোস্টনাম ভেরিফায়ার তৈরির পরিবর্তে, আপনি SSLConnicationSketFactory.ALLOW_ALL_HOSTNAME_VERIFIER ব্যবহার করতে পারেন।
holmis83

@ সমৃদ্ধ 95 দ্বারা নীচে চিহ্নিত হিসাবে, এইচটিটিপিপ্লিনেন্টগুলির জন্য ডিফল্ট হ'ল আপনাকে একটি পুলিংএইচটিপি ক্লায়েন্ট দেওয়া হয়, তাই এটি প্রায়শই প্রাসঙ্গিক। আমার এটির প্রয়োজনীয়তার সন্ধান করার আগে আমাকে এই উত্তরগুলির বেশ কয়েকটি চেষ্টা করতে হয়েছিল।
সানসিয়ার

1
এটি ওয়েবস্পিয়ারে প্রয়োগ করার চেষ্টা করেছিল এবং "java.security.KeyStoreException: IBMTrustManager: বিশ্বাসের স্টোরটিতে অ্যাক্সেস করতে সমস্যা java.io.IOException: অবৈধ কীস্টোর ফর্ম্যাট" আপনাকে কীস্টোর ট্রাস্টস্টোর = কীস্টোর.জেটইনস্ট্যান্স (কীস্টোর.জিটডিফল্ট টাইপ)) পাস করতে হবে;
builder.loadTrustMaterial এ

1
প্রকৃতপক্ষে, এইচটিটিপিপ্লায়েন্ট ৪.৫ সহ, উভয়ই কাজ করবে HttpClients.custom().setConnectionManager(cm).build()এবং HttpClients.custom().setSSLSocketFactory(connectionFactory).build()কাজ করবে, তাই আপনাকে একটি তৈরি করতে হবে নাPoolingHttpClientConnectionManager
সোলম্যাচাইন

কীভাবে পুলিংএইচটিপিপিপ্লায়েন্ট কনসেকশন ম্যানেজার ব্যবহার করবেন এটি তৈরি করার পরে, আমার কোডটি কাজ করছে তবে আমি জানতে চাই যে সংযোগ পুলিং কাজ করে কিনা
Labeo

34

@ ম্যামপ্রোভ্যাটো এর উত্তরের যোগ হিসাবে, আপনি যদি কেবল স্ব-স্বাক্ষর না করে সমস্ত শংসাপত্রগুলিতে বিশ্বাস করতে চান তবে আপনি (আপনার কোডের স্টাইলে) করতে চান

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

বা (আমার নিজের কোড থেকে সরাসরি কপি-পেস্ট):

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

এবং আপনি হোস্টনামের যাচাইকরণটিও এড়িয়ে যেতে চান, আপনাকে সেট করতে হবে

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

যেমন. (ALLOW_ALL_HOSTNAME_VERIFIER হ্রাস করা হয়েছে)।

বাধ্যতামূলক সতর্কতা: আপনার সত্যই এটি করা উচিত নয়, সমস্ত শংসাপত্র গ্রহণ করা একটি খারাপ জিনিস। তবে এমন কিছু বিরল ব্যবহারের ঘটনা রয়েছে যেখানে আপনি এটি করতে চান।

পূর্বে প্রদত্ত কোডের নোট হিসাবে, আপনি প্রতিক্রিয়া বন্ধ করতে চাইবেন এমনকি যদি httpclient.execute () একটি ব্যতিক্রম ছুঁড়ে ফেলে

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

উপরের কোড ব্যবহার করে পরীক্ষা করা হয়েছিল

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

এবং আগ্রহীদের জন্য, আমার সম্পূর্ণ পরীক্ষার সেটটি এখানে:

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

( গিথুবে পরীক্ষামূলক প্রকল্পে কাজ করা )


1
এইচটিটিপিসিলেট # এক্সিকিউটেট ব্যতিক্রমের ক্ষেত্রে কোনও শূন্য প্রতিক্রিয়া অবজেক্ট ফিরিয়ে আনবে না। তদুপরি, স্টক এইচটিটিপিপ্লায়েন্ট প্রয়োগগুলি অনুরোধ কার্যকর করার সময় কোনও ব্যতিক্রম ক্ষেত্রে লিজড সংযোগের মতো সমস্ত সিস্টেমের রিসোর্সগুলির স্বয়ংক্রিয়ভাবে হ্রাস নিশ্চিত করবে। মাভ্রোপ্রোভাটো দ্বারা ব্যবহৃত ব্যতিক্রম হ্যান্ডলিং পুরোপুরি পর্যাপ্ত।
Ok2c

@ ক্লোজেবল ইন্টারফেসের মূল বিন্যাসটি হ'ল "[...] স্ট্রিমটি বন্ধ করা এবং এর সাথে সম্পর্কিত যে কোনও সিস্টেমের রিসোর্সগুলি মুক্তি দেওয়া If যদি স্ট্রিমটি ইতিমধ্যে বন্ধ হয়ে যায় তবে এই পদ্ধতির সাথে অনুরোধ করার কোনও প্রভাব নেই" " সুতরাং এটির প্রয়োজন না হলেও এটি ব্যবহার করা ভাল অনুশীলন। এছাড়াও, আমি নাল প্রতিক্রিয়া ফিরিয়ে দেওয়ার মন্তব্যটি বুঝতে পারি না - অবশ্যই এটি হয় না, যদি এটি একটি ব্যতিক্রম ছুঁড়ে দেয় তবে এটি কিছুই ফেরায় না?
eis

1
এ্যাপাচি HttpClient কখনো কখনো একটি ফাঁকা বা আংশিকভাবে সক্রিয়া প্রতিক্রিয়া বস্তু ফেরৎ। এটি কতবার বন্ধ করার জন্য আহ্বান জানায় তার সাথে কিছুই করার নেই, তবে শেষ অবধি সম্পূর্ণ অপ্রয়োজনীয় নাল চেক করতে হবে
Ok2c

@ ওলেগ এবং আমি যে কোডটি দিয়েছি তা কখনই করে না তা ধরে নিলে এটি কোনও শূন্য বা আংশিকভাবে প্রাথমিক প্রতিক্রিয়ার বস্তুটি ফিরে আসবে, এমনকি এমন কেসও পরীক্ষা করবে। আপনি কী বলছেন তা আমার কাছে নেই?
eis

1
[ দীর্ঘশ্বাস ] যা এইচটিপিআরস্পোনস কখনই বাতিল হতে পারে না এবং এটি সম্পূর্ণরূপে অপ্রয়োজনীয় যে কোনও ক্ষেত্রে ব্যতিক্রম হলে # এক্সিকিউট পদ্ধতিটি কোনও প্রতিক্রিয়া ফিরিয়ে না দিয়ে সমাপ্ত হবে ;-)
Ok2c

22

ভাসেকটের উত্তরটির সাথে একটি ছোট সংযোজন:

পুলিংএইচটিপিপিলেট ক্লিনিকেশন ম্যানেজার ব্যবহার করার সময় সকেটফ্যাক্টরিআগ্রিস্ট্রি সহ সরবরাহিত সমাধান কাজ করে।

তবে, সরল HTTP- র মাধ্যমে সংযোগগুলি আর কাজ করে না। এগুলি পুনরায় কাজ করার জন্য আপনাকে এগুলির জন্য HTTP প্রোটোকলের জন্য একটি প্লেন সংযোগসকেটফ্যাক্টরি যুক্ত করতে হবে:

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

আমি বিশ্বাস করি httpপ্রোটোকল PlainConnectionSocketFactory ডিফল্টরূপে ব্যবহার করছে । আমি কেবল নিবন্ধভুক্ত করেছি httpsএবং httpclientএখনও প্লেইন এইচটিটিপি ইউআরএল পেতে পারি। সুতরাং আমি মনে করি না এই পদক্ষেপটি প্রয়োজনীয়।
সোলমাচাইন

@ সোলমাচাইন এটির জন্য নয়PoolingHttpClientConnectionManager
এমেসেজার

15

বিভিন্ন বিকল্পের চেষ্টা করার পরে, নিম্নলিখিত কনফিগারেশনটি http এবং 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();

আমি HTTP- ক্লায়েন্ট ব্যবহার করছি 4.3.3 -

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


1
একটি বিস্তৃত, পুরোপুরি কার্যকর উদাহরণ দেওয়ার জন্য ধন্যবাদ! আমি পূর্ববর্তী সমাধানগুলি সহ একাধিক সমস্যাগুলি আঘাত করছিলাম এবং এটি প্রচুরভাবে সহায়তা করেছিল helped বিভ্রান্তি যোগ করে একই নামের একাধিক ক্লাস থাকায় আপনি আমদানির বিবৃতি সরবরাহ করতে সহায়তা করেছেন।
হেলমি

8

সহজ এবং খাটো কাজের কোড:

আমরা HTTPClient 4.3.5 ব্যবহার করছি এবং আমরা স্ট্যাকওভারফ্লোতে প্রায় সমস্ত সমাধানের উপস্থিতি চেষ্টা করেছি কিন্তু সমস্যাটি চিন্তাভাবনা করার পরে, আমরা নীচের কোডটিতে আসি যা নিখুঁতভাবে কাজ করে, কেবল এইচটিটিপিপ্লিনেন্ট ইনস্ট্যান্স তৈরির আগে এটি যুক্ত করুন।

কিছু অনুরোধ যা আপনি পোস্ট অনুরোধ করতে ব্যবহার করেন ...

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

সাধারণ ফর্মটিতে এইচটিটিপিপোস্ট উদাহরণটি কল করা এবং ব্যবহার চালিয়ে যান


আমরা হেডারে কীভাবে ডেটা পোস্ট করতে পারি? যদি আমরা তা করি, তবে HTTP / 1.1 400 খারাপ অনুরোধটি দেখুন

6

উপরের কৌশলগুলির একটি কার্যনির্বাহী পাতন এখানে দেওয়া হয়েছে, "কার্ল - আইন সুরক্ষা" এর সমতুল্য:

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

5

HTTP ক্লায়েন্ট 4.5 ব্যবহার করার সময় আমাকে কোনও হোস্টনাম (পরীক্ষার উদ্দেশ্যে) অনুমতি দেওয়ার জন্য javasx.net.ssl.HostnameVerifier ব্যবহার করতে হয়েছিল। এখানে আমি শেষ করে যাচ্ছি:

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

হোস্ট-নেম ভিরিফায়ার বাস্তবায়ন HTTPClient 4.5 এর জন্য সমস্যার সমাধান করেছে।
digz6666

যারা ল্যাম্বডাস (JDK1.8) পছন্দ করেন তাদের SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);সাথে প্রতিস্থাপন করতে পারেন SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);। এটি বেনাম শ্রেণি এড়ায় এবং কোডটি আরও কিছুটা পঠনযোগ্য করে তোলে।
ভিলিঙ্কো

3

উপরের PoolingHttpClientConnectionManagerসাথে Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build(); আপনি কোডটি shoudl ব্যবহার PoolingNHttpClientConnectionManagerকরে একটি অ্যাসিঙ্ক্রোনাস httpclient চাইলে নীচের মত হতে পারে

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

3

আপনি যদি ব্যবহার করে থাকেন তবে HttpClient 4.5.xআপনার কোডটি নিম্নলিখিতগুলির মতো হতে পারে:

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

আমার পক্ষে কাজ করেনি। আমি এইচটিপিপিলেট ব্যবহার করছি: 4.5। এবং এইচটিপিপোর 4.4.9
বিজয় কুমার

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

2

অ্যাপাচি এইচটিটিপি ক্লায়েন্টের সমস্ত শংসাপত্রগুলি বিশ্বাস করুন

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

এটি httpclient 4.5.4 এর সাথে ভালভাবে কাজ করেছে, কেবল এটি সম্পূর্ণ কপিটি অনুলিপি করুন এবং আটকান।
Sathya

1

(আমি ভাসেক্টের উত্তরে সরাসরি একটি মন্তব্য যুক্ত করতে পারি তবে আমার যথেষ্ট সুনামের পয়েন্ট নেই (সেখানে যুক্তি নিশ্চিত নয়)

যাইহোক ... আমি যা বলতে চেয়েছিলাম তা হ'ল আপনি যদি স্পষ্টভাবে কোনও পুলিং সংযোগ তৈরি / জিজ্ঞাসা নাও করেন তবে এর অর্থ এই নয় যে আপনি একটি পাচ্ছেন না।

মূল সমাধানটি কেন আমার পক্ষে কার্যকর হয়নি তা বোঝার চেষ্টা করতে গিয়ে আমি পাগল হয়ে যাচ্ছিলাম, তবে ভাসেকটের উত্তরটি "আমার ক্ষেত্রে প্রযোজ্য নয়" বলে আমি এড়িয়ে গেছি - ভুল!

আমি যখন আমার স্ট্যাক-ট্রেসটি ঘুরে দেখছিলাম তখন নীচু হয়ে দেখলাম এর মাঝখানে একটি পুলিংকনেকশন দেখলাম। ঠুং ঠুং শব্দ - আমি তার সংযোজন এবং সাফল্য ক্লান্ত !! (আমাদের ডেমো আগামীকাল এবং আমি মরিয়া হয়ে উঠছিলাম) :-)


0

এসএসএল শংসাপত্র যাচাই না করে আপনি এইচটিটিপিপ্লায়েন্ট উদাহরণ পেতে নিম্নলিখিত কোড স্নিপেট ব্যবহার করতে পারেন।

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

0

সোনার সুরক্ষা সতর্কতা ঠিক করতে উপরের @ ডিভবিজারো থেকে উত্তর দেওয়ার জন্য কিছুটা সামান্য টুইট

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

0

প্রাথমিকভাবে, আমি বিশ্বাসের কৌশল ব্যবহার করে লোকালহোস্টের জন্য অক্ষম করতে সক্ষম হয়েছি, পরে আমি নূপহোস্টনামভেরিফায়ার যুক্ত করেছি। এখন এটি লোকালহোস্ট এবং যেকোন মেশিনের নামের জন্য কাজ করবে

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();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.