এইচটিটিপিএস-এর মাধ্যমে এইচটিপিপিপ্লায়েন্ট ব্যবহার করে সমস্ত শংসাপত্রের উপর বিশ্বাস রাখা


393

HttpClientওভার এইচটিএসপিএস সম্পর্কে সম্প্রতি একটি প্রশ্ন পোস্ট করেছে ( এখানে পাওয়া গেছে )। আমি কিছুটা অগ্রগতি করেছি, তবে আমি নতুন সমস্যা নিয়ে চলেছি। আমার শেষ সমস্যাটির মতো, আমার কাছে এমন কোনও উদাহরণ খুঁজে পাচ্ছে না যা আমার পক্ষে কাজ করে। মূলত, আমি চাইছি আমার ক্লায়েন্টটি কোনও শংসাপত্র গ্রহণ করবে (কারণ আমি কেবলমাত্র একটি সার্ভারের দিকে ইশারা করছি) তবে আমি একটি পেতে থাকিjavax.net.ssl.SSLException: Not trusted server certificate exception.

সুতরাং এই আমার আছে:


    public void connect() throws A_WHOLE_BUNCH_OF_EXCEPTIONS {

        HttpPost post = new HttpPost(new URI(PROD_URL));
        post.setEntity(new StringEntity(BODY));

        KeyStore trusted = KeyStore.getInstance("BKS");
        trusted.load(null, "".toCharArray());
        SSLSocketFactory sslf = new SSLSocketFactory(trusted);
        sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme ("https", sslf, 443));
        SingleClientConnManager cm = new SingleClientConnManager(post.getParams(),
                schemeRegistry);

        HttpClient client = new DefaultHttpClient(cm, post.getParams());
        HttpResponse result = client.execute(post);
    }

এবং আমি যে ত্রুটিটি পাচ্ছি তা এখানে:

    W/System.err(  901): javax.net.ssl.SSLException: Not trusted server certificate 
    W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:360) 
    W/System.err(  901):    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92) 
    W/System.err(  901):    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:321) 
    W/System.err(  901):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:129) 
    W/System.err(  901):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
    W/System.err(  901):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
    W/System.err(  901):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348) 
    W/System.err(  901):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
    W/System.err(  901):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
    W/System.err(  901):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
    W/System.err(  901):    at me.harrisonlee.test.ssl.MainActivity.connect(MainActivity.java:129) 
    W/System.err(  901):    at me.harrisonlee.test.ssl.MainActivity.access$0(MainActivity.java:77) 
    W/System.err(  901):    at me.harrisonlee.test.ssl.MainActivity$2.run(MainActivity.java:49) 
    W/System.err(  901): Caused by: java.security.cert.CertificateException: java.security.InvalidAlgorithmParameterException: the trust anchors set is empty 
    W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:157) 
    W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:355) 
    W/System.err(  901):    ... 12 more 
    W/System.err(  901): Caused by: java.security.InvalidAlgorithmParameterException: the trust anchors set is empty 
    W/System.err(  901):    at java.security.cert.PKIXParameters.checkTrustAnchors(PKIXParameters.java:645) 
    W/System.err(  901):    at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:89) 
    W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.<init>(TrustManagerImpl.java:89) 
    W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl.engineGetTrustManagers(TrustManagerFactoryImpl.java:134) 
    W/System.err(  901):    at javax.net.ssl.TrustManagerFactory.getTrustManagers(TrustManagerFactory.java:226)W/System.err(  901):     at org.apache.http.conn.ssl.SSLSocketFactory.createTrustManagers(SSLSocketFactory.java:263) 
    W/System.err(  901):    at org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:190) 
    W/System.err(  901):    at org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:216) 
    W/System.err(  901):    at me.harrisonlee.test.ssl.MainActivity.connect(MainActivity.java:107) 
    W/System.err(  901):    ... 2 more

17
অভ্যন্তরীণ ব্যবহারের জন্য আমার এটি করা দরকার ছিল। আমি সত্যিই আশা করি যে আপনি আপনার সংস্থার বাইরের ব্যবহারকারীদের আপনার অ্যাপটি ব্যবহার করতে দিচ্ছেন না যেহেতু আপনি এটি মধ্যম আক্রমণে মানুষের জন্য উন্মুক্ত করেছেন এবং তারপরে কেউ তাদের অধিবেশন হাইজ্যাক করার ঝুঁকিতে পড়বে। তবুও, আমি আসল শংসাপত্র হাতে না পাওয়া পর্যন্ত আমাকে কিছু পরীক্ষার জন্য এই অস্থায়ী করতে হবে ..... আশা করি আপনি একই অস্থায়ী কারণেই এটি করছেন বা অ্যাপটি কেবল অভ্যন্তরীণভাবে ব্যবহার করা হচ্ছে না।
ডিন হিলার 21

আমি এই সমাধানগুলি 4.3 অ্যাপাচি HTTP ক্লায়েন্টে চেষ্টা করেছি, তবে সেগুলি বেশিরভাগই হ্রাস পেয়েছে। : এখানে অবচিত করা হয় না সমাধান stackoverflow.com/a/18941950/2039471
আলেকজান্ডার Chzhen

জাভা 1.6 এর এসএনআই সমর্থন নেই যা এই পরিস্থিতিতেও সমস্যাযুক্ত - আপনি যদি অনুরোধটি যথাযথভাবে নির্মাণ না করেন তবে আপনি একটি শংসাপত্র পেতে পারেন যা অনুরোধটির সাথে মেলে না। দেখুন issues.apache.org/jira/browse/HTTPCLIENT-1119
Bron ডেভিস

2
এই প্রশ্নটি দ্য ওয়ার্ল্ড পেপারের সর্বাধিক বিপদজনক কোডে মিথ্যা যুক্তির উদাহরণ হিসাবে উদ্ধৃত করা হয়েছে। (গবেষণা পত্র: cs.utexas.edu/~shmat/shmat_ccs12.pdf )
এম কে_অক্টো

উত্তর:


421

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

আপনার প্রশ্নটি আমি কেবল জানতে চাই। আমি কিছু অনুসন্ধান করার পরে, উপসংহারটি নিম্নরূপ।

এইচটিপিপি্লিয়েন্ট উপায়ে, আপনি org.apache.http.conn.ssl.SSLSketFactory থেকে একটি কাস্টম ক্লাস তৈরি করা উচিত, একটিও org.apache.http.conn.ssl.SSLSketFactory নিজেই নয়। এই পোস্টে কিছু সংকেত পাওয়া যাবে কাস্টম এসএসএল হ্যান্ডলিং অ্যান্ড্রয়েড 2.2 FroYo এ কাজ করা বন্ধ করে দিয়েছে

একটি উদাহরণ যেমন ...

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.conn.ssl.SSLSocketFactory;
public class MySSLSocketFactory extends SSLSocketFactory {
    SSLContext sslContext = SSLContext.getInstance("TLS");

    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(truststore);

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

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

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }
}

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

public HttpClient getNewHttpClient() {
    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);

        MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}

বিটিডাব্লু, নীচের লিঙ্কটি এমন কোনও ব্যক্তির জন্য যাঁরা এইচটিটিপিআরএল সংযোগ সমাধান খুঁজছেন। এইচটিপিএস সংযোগ অ্যান্ড্রয়েড

আমি উপরোক্ত উপরোক্ত দুটি ধরণের সমাধানগুলি পরীক্ষা করেছি এবং তারা সকলেই আমার ক্ষেত্রে মনোযোগের মতো কাজ করে। শেষ অবধি, এইচটিপিআরএল সংযোগ ব্যবহার পুনঃনির্দেশ সমস্যার সম্মুখীন হতে পারে তবে এটি বিষয়টির বাইরে।

দ্রষ্টব্য: আপনি সমস্ত শংসাপত্রগুলিতে বিশ্বাস করার সিদ্ধান্ত নেওয়ার আগে আপনার সম্ভবত সাইটটি পুরোপুরি ভালভাবে জানা উচিত এবং এটি শেষ ব্যবহারকারীর পক্ষে ক্ষতিকারক হবে না।

প্রকৃতপক্ষে, আপনি যে ঝুঁকি নিয়েছেন সেগুলি সাবধানতার সাথে বিবেচনা করা উচিত, হ্যাকারের মক সাইটের প্রভাব সহ নীচের মন্তব্যে উল্লিখিত যা আমি গভীরভাবে প্রশংসা করেছি। কিছু পরিস্থিতিতে, যদিও সমস্ত শংসাপত্রের যত্ন নেওয়া কঠিন হতে পারে তবে সেগুলির উপর আস্থা রাখার জন্য অন্তর্নিহিত ত্রুটিগুলি আরও ভালভাবে জানতে হবে।


150
এই উত্তরে সম্ভবত লক্ষ্য করা উচিত যে সমস্ত শংসাপত্রের উপর বিশ্বাস করা মারাত্মকভাবে নিরাপত্তাহীন এবং এসএসএল এর পুরো উদ্দেশ্যকে বাতিল করে দেয় ...
ইয়ানোকওয়া

22
@ সুইউনি - আপনি যে সার্ভারের সাথে কথা বলছেন তা আপনি যে কথা বলছেন তা গ্যারান্টিযুক্ত ছাড়া ব্যতীত। কেউ যদি ডিএনএস সার্ভারটি আপ করে থাকেন তবে আপনি হ্যাকারের সার্ভারের সাহায্যে একটি এনক্রিপশন কীটি যোগাযোগ করতে পারেন।
রিচার্ড জাজায়

12
@ সুইউনি অন্য কথায় আপনি এখন ম্যান-ইন-মধ্য-আক্রমণের জন্য দায়বদ্ধ। আপনার মনে রাখতে হবে যে কোডটি নির্দিষ্টকরণের সাথে মেলে না: জাভাদোকটি পরীক্ষা করুন। getAcceptedIssuers()নাল ফেরার অনুমতি নেই
লার্নের মারকুইস

25
-1 কারণ সমস্ত শংসাপত্র গ্রহণ করা একটি ভয়ানক ধারণা। এটি খুব খারাপ যে এমন অনেকগুলি ব্লগ এবং টিউটোরিয়াল রয়েছে যা জাভা বিকাশকারীদের ভুল কাজ করার পথে আনন্দের সাথে গাইড করে।
টিম বেন্ডার

57
+1 কারণ আমার কেবলমাত্র ডিবাগিংয়ের উদ্দেশ্যে একটি দ্রুত সমাধান প্রয়োজন। অন্যরা উল্লিখিত সুরক্ষা উদ্বেগের কারণে আমি উত্পাদনে এটি ব্যবহার করব না, তবে পরীক্ষার জন্য আমার ঠিক এটির প্রয়োজন ছিল। ধন্যবাদ!
ড্যানিশেশন

495

আপনার কাছে মূলত httpclient ব্যবহার করে অ্যান্ড্রয়েডে "বিশ্বাসযোগ্য নয়" ব্যতিক্রমটি ঠিক করার জন্য চারটি সম্ভাব্য সমাধান রয়েছে:

  1. সমস্ত শংসাপত্র বিশ্বাস। আপনি কী করছেন তা যদি আপনি সত্যিই না জানেন তবে এটি করবেন না।
  2. এমন একটি কাস্টম এসএসএসকেটফ্যাক্টরি তৈরি করুন যা কেবলমাত্র আপনার শংসাপত্রকেই বিশ্বাস করে। আপনি যতটা সার্ভারের সাথে সংযোগ করতে চলেছেন তা ঠিক ততক্ষণ আপনি জানেন তবে আপনি যত তাড়াতাড়ি একটি ভিন্ন এসএসএল শংসাপত্রের সাথে একটি নতুন সার্ভারের সাথে সংযোগ স্থাপন করতে হবে, আপনাকে আপনার অ্যাপ্লিকেশনটি আপডেট করতে হবে।
  3. একটি কীস্টোর ফাইল তৈরি করুন যাতে অ্যান্ড্রয়েডের শংসাপত্রগুলির "মাস্টার তালিকা" থাকে, তারপরে আপনার নিজের যুক্ত করুন। যদি এই শংসাপত্রগুলির মধ্যে কোনওটির মেয়াদ শেষ হয়ে যায় তবে সেগুলি আপনার অ্যাপে আপডেট করার জন্য আপনি দায়বদ্ধ। আমি এটি করার কোনও কারণ ভাবতে পারি না।
  4. একটি কাস্টম এসএসএসকেটফ্যাক্টরি তৈরি করুন যা অন্তর্নির্মিত শংসাপত্র কীস্টোর ব্যবহার করে তবে ডিফল্টর সাথে যাচাই করতে ব্যর্থ যে কোনও কিছুর জন্য বিকল্প কীস্টোরের পিছনে পড়ে।

এই উত্তরটিতে সমাধান # 4 ব্যবহার করা হয়েছে যা আমার কাছে সবচেয়ে শক্তিশালী বলে মনে হয়।

সমাধানটি এমন একটি এসএসএলসকেটফ্যাক্টরি ব্যবহার করা হবে যা একাধিক কীস্টোর গ্রহণ করতে পারে, আপনাকে নিজের শংসাপত্র দিয়ে আপনার নিজস্ব কীস্টোর সরবরাহ করতে দেয়। এটি আপনাকে অতিরিক্ত শীর্ষ-স্তরের শংসাপত্রগুলি লোড করতে দেয় যেমন থাওতে যা কিছু Android ডিভাইসে হারিয়ে যেতে পারে on এটি আপনাকে নিজের স্ব-স্বাক্ষরিত শংসাপত্রগুলিও লোড করতে দেয়। এটি প্রথমে বিল্ট-ইন ডিফল্ট ডিভাইস শংসাপত্রগুলি ব্যবহার করবে এবং কেবলমাত্র প্রয়োজনীয় হিসাবে আপনার অতিরিক্ত শংসাপত্রগুলিতে ফিরে আসবে।

প্রথমত, আপনি নির্ধারণ করতে চান যে আপনি আপনার কীস্টোরের কোন সার্টিটি মিস করছেন। নিম্নলিখিত কমান্ড চালান:

openssl s_client -connect www.yourserver.com:443

এবং আপনি নীচের মত আউটপুট দেখতে পাবেন:

Certificate chain
 0 s:/O=www.yourserver.com/OU=Go to 
   https://www.thawte.com/repository/index.html/OU=Thawte SSL123 
   certificate/OU=Domain Validated/CN=www.yourserver.com
   i:/C=US/O=Thawte, Inc./OU=Domain Validated SSL/CN=Thawte DV SSL CA
 1 s:/C=US/O=Thawte, Inc./OU=Domain Validated SSL/CN=Thawte DV SSL CA
   i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 
   2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA

আপনি দেখতে পাচ্ছেন, আমাদের মূল শংসাপত্রটি থাওতে from আপনার সরবরাহকারীর ওয়েবসাইটে যান এবং সংশ্লিষ্ট শংসাপত্রটি সন্ধান করুন। আমাদের জন্য, এটি এখানে ছিল এবং আপনি দেখতে পাচ্ছেন যে আমাদের যা প্রয়োজন তা হ'ল একটি কপিরাইট 2006।

আপনি যদি স্ব-স্বাক্ষরিত শংসাপত্রটি ব্যবহার করেন তবে আপনার ইতিমধ্যে আপনার স্বাক্ষরকারী শংসাপত্র হওয়ায় আপনার আগের পদক্ষেপটি করার দরকার নেই।

তারপরে, অনুপস্থিত স্বাক্ষর শংসাপত্র সহ একটি কীস্টোর ফাইল তৈরি করুন। ক্রেজিবব- এ অ্যান্ড্রয়েডে কীভাবে এটি করা যায় তার বিশদ রয়েছে , তবে নিম্নলিখিতটি করার জন্য ধারণাটি রয়েছে:

আপনার যদি এটি ইতিমধ্যে না থাকে তবে বাউন্সি ক্যাসল সরবরাহকারী লাইব্রেরিটি ডাউনলোড করুন: http://www.bouncycastle.org/latest_releases.html থেকে । এটি নীচে আপনার ক্লাসপথে যাবে।

সার্ভার থেকে শংসাপত্রটি বের করতে এবং একটি পেম ফাইল তৈরি করতে একটি কমান্ড চালান। এই ক্ষেত্রে, mycert.pem।

echo | openssl s_client -connect ${MY_SERVER}:443 2>&1 | \
 sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > mycert.pem

তারপরে কীস্টোর তৈরি করতে নিম্নলিখিত কমান্ডগুলি চালান।

export CLASSPATH=/path/to/bouncycastle/bcprov-jdk15on-155.jar
CERTSTORE=res/raw/mystore.bks
if [ -a $CERTSTORE ]; then
    rm $CERTSTORE || exit 1
fi
keytool \
      -import \
      -v \
      -trustcacerts \
      -alias 0 \
      -file <(openssl x509 -in mycert.pem) \
      -keystore $CERTSTORE \
      -storetype BKS \
      -provider org.bouncycastle.jce.provider.BouncyCastleProvider \
      -providerpath /path/to/bouncycastle/bcprov-jdk15on-155.jar \
      -storepass some-password

আপনি লক্ষ্য করবেন যে উপরের স্ক্রিপ্টটি ফলাফলটি রাখে res/raw/mystore.bks। এখন আপনার কাছে এমন একটি ফাইল রয়েছে যা আপনি আপনার অ্যান্ড্রয়েড অ্যাপে লোড করুন যা নিখোঁজ শংসাপত্র সরবরাহ করে।

এটি করার জন্য, এসএসএল স্কিমের জন্য আপনার এসএসএলসকেটফ্যাক্টরি নিবন্ধ করুন:

final SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", createAdditionalCertsSSLSocketFactory(), 443));

// and then however you create your connection manager, I use ThreadSafeClientConnManager
final HttpParams params = new BasicHttpParams();
...
final ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params,schemeRegistry);

আপনার এসএসএলসকেটফ্যাক্টরি তৈরি করতে:

protected org.apache.http.conn.ssl.SSLSocketFactory createAdditionalCertsSSLSocketFactory() {
    try {
        final KeyStore ks = KeyStore.getInstance("BKS");

        // the bks file we generated above
        final InputStream in = context.getResources().openRawResource( R.raw.mystore);  
        try {
            // don't forget to put the password used above in strings.xml/mystore_password
            ks.load(in, context.getString( R.string.mystore_password ).toCharArray());
        } finally {
            in.close();
        }

        return new AdditionalKeyStoresSSLSocketFactory(ks);

    } catch( Exception e ) {
        throw new RuntimeException(e);
    }
}

এবং অবশেষে, অতিরিক্তকিস্টোরস এসএসএলসকেটফ্যাক্টরি কোড, যা আপনার নতুন কীস্টোর গ্রহণ করে এবং অন্তর্নির্মিত কীস্টোর কোনও এসএসএল শংসাপত্রকে বৈধতা দিতে ব্যর্থ হয়েছে কিনা তা পরীক্ষা করে:

/**
 * Allows you to trust certificates from additional KeyStores in addition to
 * the default KeyStore
 */
public class AdditionalKeyStoresSSLSocketFactory extends SSLSocketFactory {
    protected SSLContext sslContext = SSLContext.getInstance("TLS");

    public AdditionalKeyStoresSSLSocketFactory(KeyStore keyStore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(null, null, null, null, null, null);
        sslContext.init(null, new TrustManager[]{new AdditionalKeyStoresTrustManager(keyStore)}, null);
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }



    /**
     * Based on http://download.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#X509TrustManager
     */
    public static class AdditionalKeyStoresTrustManager implements X509TrustManager {

        protected ArrayList<X509TrustManager> x509TrustManagers = new ArrayList<X509TrustManager>();


        protected AdditionalKeyStoresTrustManager(KeyStore... additionalkeyStores) {
            final ArrayList<TrustManagerFactory> factories = new ArrayList<TrustManagerFactory>();

            try {
                // The default Trustmanager with default keystore
                final TrustManagerFactory original = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                original.init((KeyStore) null);
                factories.add(original);

                for( KeyStore keyStore : additionalkeyStores ) {
                    final TrustManagerFactory additionalCerts = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                    additionalCerts.init(keyStore);
                    factories.add(additionalCerts);
                }

            } catch (Exception e) {
                throw new RuntimeException(e);
            }



            /*
             * Iterate over the returned trustmanagers, and hold on
             * to any that are X509TrustManagers
             */
            for (TrustManagerFactory tmf : factories)
                for( TrustManager tm : tmf.getTrustManagers() )
                    if (tm instanceof X509TrustManager)
                        x509TrustManagers.add( (X509TrustManager)tm );


            if( x509TrustManagers.size()==0 )
                throw new RuntimeException("Couldn't find any X509TrustManagers");

        }

        /*
         * Delegate to the default trust manager.
         */
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            final X509TrustManager defaultX509TrustManager = x509TrustManagers.get(0);
            defaultX509TrustManager.checkClientTrusted(chain, authType);
        }

        /*
         * Loop over the trustmanagers until we find one that accepts our server
         */
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            for( X509TrustManager tm : x509TrustManagers ) {
                try {
                    tm.checkServerTrusted(chain,authType);
                    return;
                } catch( CertificateException e ) {
                    // ignore
                }
            }
            throw new CertificateException();
        }

        public X509Certificate[] getAcceptedIssuers() {
            final ArrayList<X509Certificate> list = new ArrayList<X509Certificate>();
            for( X509TrustManager tm : x509TrustManagers )
                list.addAll(Arrays.asList(tm.getAcceptedIssuers()));
            return list.toArray(new X509Certificate[list.size()]);
        }
    }

}

আরে @ এমএমবি, এটি আমার সমস্যার সঠিক উত্তর বলে মনে হচ্ছে তবে আমি এখনও কোনও এসএসএল সংযোগ পাইনি। আপনি কি দয়া করে এটি একবার দেখে নিতে পারেন? http://stackoverflow.com/questions/7822381/need-help-understanding-certificate-chains
ম্যাথিয়াস বি

এমএমবি দুর্দান্ত লেখার জন্য ধন্যবাদ! আমি মাঝে মাঝে একটি সত্যই দীর্ঘ দেরী এবং তারপরে একটি javax.net.ssl.SSLException: পড়ার ত্রুটি :. কোন ধারণা? সমাধান যদি স্ট্যাকওভারফ্লো / প্রশ্নগুলি / ৫৯৯৯৩০৮ / অ্যান্ড্রয়েড ২২-৩-৪-এসএল-প্রবলেমের মতো হয় তবে আমি কীভাবে একটি সময়সীমা সেট করতে পারি ?
এডউইন ইভান্স

3
@ এমএমবি, আপনি কি বলতে পারবেন যে আমি এই কোডটি রফতানি করা উচিত যেখানে CLASSPATH = bcprov-jdk16-145.jar সের্তস্টোর = রেস / কাঁচা / মাইস্টোর.বক্স যদি [-a ER সার্টিস্টোর] থাকে; তারপরে আরএম $ সার্টেস্টোর || 1 ফাই কীটোউল exit -Import \ -v \ -trustcacerts exit -alias 0 \-ফাইল <(ওপেনসেল x509 -আর মাইসার্ট.পিএম) \ -keystore ER CERTSTORE। -storetype বি কেএস pro -প্রভাইডার org.bouncycastle.jce.provider। বাউনিসিস্টলপ্রভাইডার pro -প্রভাইডারপথ / অ্যাসার / শের / জাভা / বিসিপ্রোভ.জার some-কিছু স্টোরপাস পাসওয়ার্ড
রিক্কি

1
আরে @ এমএমবি আমি আমার অ্যাপ্লিকেশানে আপনার সলিউশন ব্যবহার এবং আমার সার্ভারের স্ব স্বাক্ষরিত শংসাপত্র ব্যবহার করে কিন্তু একটি পাচ্ছি CertificateException () মধ্যে checkServerTrusted () পদ্ধতি। আমি মন্তব্য করার চেষ্টা করেছি যে ব্যতিক্রম নিক্ষেপ, এবং এটি কার্যকর। যদি এটি আমার সার্ভার শংসাপত্রকে বৈধতা দেয় না তবে আমি অন্য উপায়ে এটি পরিচালনা করতে পারি, আপনি কি দয়া করে এই ক্ষেত্রে সেরা সমাধানটি কোনটি গাইড করতে পারেন?
অঙ্কিত

7
এটি সঠিক উত্তর হিসাবে চিহ্নিত করা উচিত। আমি কখনও এসও-তে দেখেছি এমন একটি সর্বাধিক নিখুঁত এবং লিখিত উত্তর। ডোপ
কাচি

74

এই কোডটি আগে যুক্ত করুন HttpsURLConnectionএবং এটি হয়ে যাবে। আমি বুঝতে পেরেছি.

private void trustEveryone() { 
    try { 
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){ 
                    public boolean verify(String hostname, SSLSession session) { 
                            return true; 
                    }}); 
            SSLContext context = SSLContext.getInstance("TLS"); 
            context.init(null, new X509TrustManager[]{new X509TrustManager(){ 
                    public void checkClientTrusted(X509Certificate[] chain, 
                                    String authType) throws CertificateException {} 
                    public void checkServerTrusted(X509Certificate[] chain, 
                                    String authType) throws CertificateException {} 
                    public X509Certificate[] getAcceptedIssuers() { 
                            return new X509Certificate[0]; 
                    }}}, new SecureRandom()); 
            HttpsURLConnection.setDefaultSSLSocketFactory( 
                            context.getSocketFactory()); 
    } catch (Exception e) { // should never happen 
            e.printStackTrace(); 
    } 
} 

এটি তোমাকে সাহায্য করবে বলে আশা করি।


22
গৃহীত উত্তরের নীচে মন্তব্যগুলি দেখুন। এই 'সমাধান' মূলত নিরাপত্তাহীন।
লার্নের মারকুইস

5
এটি আদর্শ প্রশ্নোত্তর সমাধান। সংক্ষিপ্ত এবং "কেবলমাত্র কাজ করে"।
স্টিভ স্মিথ

5
পরীক্ষার উদ্দেশ্যে সঠিক উত্তর !!! এবং হ্যাঁ উত্পাদনে এটি ব্যবহার করা খারাপ ধারণা, তবে আসুন ... এটি প্রশ্নের শিরোনামের দিকে তাকানো প্রত্যেকের কাছে পরিষ্কার হওয়া উচিত। এটি এখনও এর সেরা / সংক্ষিপ্ত / একই (ইন) সুরক্ষা স্তরের সাথে উত্তর দেয়!
লেবীয়

34

এটি একটি খারাপ ধারণা। কোনও শংসাপত্রের উপর আস্থা রাখা কোনও এসএসএল না ব্যবহারের চেয়ে কিছুটা বেশি (খুব) ভাল। আপনি যখন বলছেন "আমি আমার ক্লায়েন্টকে কোনও শংসাপত্র গ্রহণ করতে চাই (কারণ আমি কেবলমাত্র একটি সার্ভারের দিকে ইঙ্গিত করছি)" আপনি ধরে নিচ্ছেন এর অর্থ এই যে কোনওরকমভাবে "একটি সার্ভারকে" দেখানো নিরাপদ, এটি কোনও পাবলিক নেটওয়ার্কে নেই।

আপনি কোনও শংসাপত্রের উপর নির্ভর করে মধ্যম আক্রমণে পুরোপুরি উন্মুক্ত। যে কেউ আপনার সাথে এবং শেষ সার্ভারের সাথে একটি পৃথক এসএসএল সংযোগ স্থাপন করে আপনার সংযোগটি প্রক্সি করতে পারে। এমআইটিএম এর পরে আপনার সম্পূর্ণ অনুরোধ এবং প্রতিক্রিয়াতে অ্যাক্সেস রয়েছে। আপনার প্রথম স্থানে এসএসএল দরকার না থাকলে (আপনার বার্তায় সংবেদনশীল কিছুই নেই, এবং প্রমাণীকরণ না করে) আপনার সমস্ত শংসাপত্রকে অন্ধভাবে বিশ্বাস করবেন না।

আপনার কীটোল ব্যবহার করে জ্যাক্সে সর্বজনীন শংসাপত্র যুক্ত করার কথা বিবেচনা করা উচিত এবং এটি আপনার সকেট কারখানাটি তৈরি করতে যেমন:

    KeyStore ks = KeyStore.getInstance("JKS");

    // get user password and file input stream
    char[] password = ("mykspassword")).toCharArray();
    ClassLoader cl = this.getClass().getClassLoader();
    InputStream stream = cl.getResourceAsStream("myjks.jks");
    ks.load(stream, password);
    stream.close();

    SSLContext sc = SSLContext.getInstance("TLS");
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");

    kmf.init(ks, password);
    tmf.init(ks);

    sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(),null);

    return sc.getSocketFactory();

এটি দেখার জন্য একটি সতর্কতা রয়েছে। শংসাপত্রটি শেষ পর্যন্ত শেষ হবে এবং কোডটি সেই সময় কাজ বন্ধ করবে। শংসাপত্রটি দেখে আপনি কখন নির্ধারণ করতে পারবেন সহজেই।


5
আপনি ক্লায়েন্ট-শংসাপত্র প্রমাণীকরণ ব্যবহার করছেন না, তাহলে ক্লায়েন্ট সাইড থেকে, আপনি একটি keymanager (ব্যবহারের প্রয়োজন হবে না nullযে SSLContext.init). You should also use the default algorithms (KMF/TMF.getDefaultAlgorithm() ), instead of hard-coding SunX509` (আরো যাতে কারণ TMF জন্য ডিফল্ট আসলে PKIX। সূর্যের / ওরাকল জেভিএম দিকে)
ব্রুনো

মূল শংসাপত্র ফাইল ব্যবহারের জন্য প্রস্তুত? (যেমন ব্রাউজারগুলি করেন)
দানি হেরের

কোথা myjks.jksথেকে এল ?
zionpi

1
@ জিয়নপি জাভা "কীটোল" ব্যবহার করে উত্পন্ন হয়েছে।
ড্যান

22

আপনি এপিআই 8 এর পর থেকে এইভাবে পরীক্ষার উদ্দেশ্যে এইচটিপিআরএল সংযোগ এসএসএল পরীক্ষা করে অক্ষম করতে পারেন:

    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    if (conn instanceof HttpsURLConnection) {
        HttpsURLConnection httpsConn = (HttpsURLConnection) conn;
        httpsConn.setSSLSocketFactory(SSLCertificateSocketFactory.getInsecure(0, null));
        httpsConn.setHostnameVerifier(new AllowAllHostnameVerifier());
    }

2
org.apache.http.conn.ssl.AllowAllHostnameVerifierঅবচয় করা হয়।
জ্যাকিগৌরভ

2
@zackygaurav মতে javadoc , AllowAllHostnameVerifierদ্বারা প্রতিস্থাপিত হয় NoopHostnameVerifier"
DLight

10

এইচটিটিপি কম্পোনেন্টসের এপিআই পরিবর্তন হয়েছে। এটি নীচের কোড সহ কাজ করে।

public static HttpClient getTestHttpClient() {
    try {
        SSLSocketFactory sf = new SSLSocketFactory(new TrustStrategy(){
            @Override
            public boolean isTrusted(X509Certificate[] chain,
                    String authType) throws CertificateException {
                return true;
            }
        }, new AllowAllHostnameVerifier());

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("https",8444, sf));
        ClientConnectionManager ccm = new ThreadSafeClientConnManager(registry);
        return new DefaultHttpClient(ccm);
    } catch (Exception e) {
        e.printStackTrace();
        return new DefaultHttpClient();
    }
}

একটি কাস্টম ট্রাস্ট কৌশল ব্যবহার করা সঠিক উত্তর। ধন্যবাদ।
ম্যাট ফ্রিডম্যান

10

Https://stackoverflow.com/a/6378872/1553004 এ উপরের কোডটি সঠিক, এটি বাদে হোস্ট-নেম যাচাইকারীকে কল করতে হবে:

    @Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
    SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    getHostnameVerifier().verify(host, sslSocket);
    return sslSocket;
}

আমি এই ফিক্সটি যুক্ত করতে স্পষ্টভাবে স্ট্যাকওভারফ্লোতে সাইন আপ করেছি। আমার সতর্কতা মনোযোগ দিন!


প্রথম সংযোগে একবার আপনি শংসাপত্রটি যাচাই করে নিলে পরবর্তী সংযোগগুলি দিয়ে আপনি কী করবেন? আপনি প্রথম সংযোগটি থেকে যে জ্ঞান অর্জন করেছেন তা কি কাজে লাগান? যদি একই নামে একটি জাল শংসাপত্র 3 সংযোগের চেষ্টাতে ব্যবহৃত হয় তবে কী হবে?
jww

6

আমি যারা httpclient-4.5 ব্যবহার করে তাদের জন্য একটি প্রতিক্রিয়া যুক্ত করছি, এবং সম্ভবত 4.4 এর জন্যও কাজ করে।

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.fluent.ContentResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;



public class HttpClientUtils{

public static HttpClient getHttpClientWithoutSslValidation_UsingHttpClient_4_5_2() {
    try {
        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(), new NoopHostnameVerifier());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); 
        return httpclient;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
}

নতুন নুপহোস্টনেম ভেরিফায়ার () ক্লাসটি কী?
মুশতাকিম আহমেদ আনসারী

1
@ মুশতাকিমআহমেডআনসারি ডক্স থেকে: "NO_OP হোস্টনেম ভেরিফায়ার মূলত হোস্টনাম যাচাইকরণ বন্ধ করে দেয় This
কিসমেকোস্টিন

দুর্দান্ত উত্তরের জন্য ধন্যবাদ hisএর জন্য আরও বেশি ভোট পাওয়া উচিত।
অভয় দ্বিবেদী

আমি কিভাবে এটা ব্যবহার করব? বা আপনি কি পরামর্শ দিচ্ছেন যে ক্লাসটি কেবল এসএসএল শংসাপত্রের যাচাইকরণের ওভাররাইড করবে?
1'18 বেহেলিট

হ্যাঁ. যে HTCClient ব্যবহৃত হবে তখন https শংসাপত্রগুলি বৈধ করবে না
raisercostin

4

সমস্ত শংসাপত্রের উপর আস্থা রাখা আমার পক্ষে সত্যিকারের বিকল্প ছিল না, সুতরাং আমি নতুন শংসাপত্রের উপর আস্থা রাখতে Https URL সংযোগ পাওয়ার জন্য নিম্নলিখিতগুলি করেছি ( http://nelenkov.blogspot.jp/2011/12/used-custom-certificate-trust-store- on.html )।

  1. শংসাপত্র পান; আমি ফায়ারফক্সে শংসাপত্রটি রফতানি করে এটি করেছি (ছোট লক আইকনে ক্লিক করুন, শংসাপত্রের বিশদটি পাবেন, রফতানিতে ক্লিক করুন), তারপরে ট্রস্টস্টোর (বিকেএস) রফতানি করার জন্য পোর্টটেল ব্যবহার করেছেন

  2. নিম্নলিখিত কোড সহ /res/raw/geotrust_cert.bks থেকে ট্রাস্টস্টোর লোড করুন:

        final KeyStore trustStore = KeyStore.getInstance("BKS");
        final InputStream in = context.getResources().openRawResource(
                R.raw.geotrust_cert);
        trustStore.load(in, null);
    
        final TrustManagerFactory tmf = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);
    
        final SSLContext sslCtx = SSLContext.getInstance("TLS");
        sslCtx.init(null, tmf.getTrustManagers(),
                new java.security.SecureRandom());
    
        HttpsURLConnection.setDefaultSSLSocketFactory(sslCtx
                .getSocketFactory());

আমি এই ত্রুটি পেয়েছি। IOExceptionjavax.net.ssl.SSLPeerUnverifiedException: No peer certificate। উপরোক্ত সেটআপটি শেষ হওয়ার পরে এইচটিটিপিপ্লিনেন্টে প্রকৃত সম্পাদনা কল করার সময় এটি করা হয়।
মাইকেল

3

এখানে 4.1.2 httpclient কোড ব্যবহার করে একটি খুব সহজ সংস্করণ। এরপরে আপনি উপযুক্ত দেখেন এমন কোনও বিশ্বাসের অ্যালগরিদমে এটি সংশোধন করা যেতে পারে।

public static HttpClient getTestHttpClient() {
    try {
        SSLSocketFactory sf = new SSLSocketFactory(new TrustStrategy(){
            @Override
            public boolean isTrusted(X509Certificate[] chain,
                    String authType) throws CertificateException {
                return true;
            }
        });
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("https", 443, sf));
        ClientConnectionManager ccm = new ThreadSafeClientConnManager(registry);
        return new DefaultHttpClient(ccm);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}

3

আমি "এমএমবি" থেকে প্রতিক্রিয়া দেখছি (জুন 16 '11 2121-এ 21), আইটেম # 4: "একটি কাস্টম এসএসএসকেটফ্যাক্টরি তৈরি করুন যা বিল্ট-ইন সার্টিফিকেট কীস্টোর ব্যবহার করে, তবে ব্যর্থ কোনও কিছুর জন্য বিকল্প কীস্টোরের পিছনে পড়ে যায়" ডিফল্ট দিয়ে যাচাই করতে। "

এটি একটি সরলীকৃত বাস্তবায়ন। সিস্টেম কীস্টোর লোড করুন এবং অ্যাপ্লিকেশন কীস্টোরের সাথে একত্রীকরণ করুন।

public HttpClient getNewHttpClient() {
    try {
        InputStream in = null;
        // Load default system keystore
        KeyStore trusted = KeyStore.getInstance(KeyStore.getDefaultType()); 
        try {
            in = new BufferedInputStream(new FileInputStream(System.getProperty("javax.net.ssl.trustStore"))); // Normally: "/system/etc/security/cacerts.bks"
            trusted.load(in, null); // no password is "changeit"
        } finally {
            if (in != null) {
                in.close();
                in = null;
            }
        }

        // Load application keystore & merge with system
        try {
            KeyStore appTrusted = KeyStore.getInstance("BKS"); 
            in = context.getResources().openRawResource(R.raw.mykeystore);
            appTrusted.load(in, null); // no password is "changeit"
            for (Enumeration<String> e = appTrusted.aliases(); e.hasMoreElements();) {
                final String alias = e.nextElement();
                final KeyStore.Entry entry = appTrusted.getEntry(alias, null);
                trusted.setEntry(System.currentTimeMillis() + ":" + alias, entry, null);
            }
        } finally {
            if (in != null) {
                in.close();
                in = null;
            }
        }

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        SSLSocketFactory sf = new SSLSocketFactory(trusted);
        sf.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}

জেকেএস থেকে বিকেএস রূপান্তর করার জন্য একটি সাধারণ মোড:

keytool -importkeystore -destkeystore cacerts.bks -deststoretype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk16-141.jar -deststorepass changeit -srcstorepass changeit -srckeystore $JAVA_HOME/jre/lib/security/cacerts -srcstoretype JKS -noprompt

* দ্রষ্টব্য: অ্যান্ড্রয়েড 4.0.০ (আইসিএস) এ ট্রাস্ট স্টোর পরিবর্তন হয়েছে, আরও তথ্য: http://nelenkov.blogspot.com.es/2011/12/ics-trust-store-implementation.html


3

যারা OAuth এর মাধ্যমে সমস্ত শংসাপত্রগুলি (পরীক্ষার উদ্দেশ্যে) কাজ করার অনুমতি দিতে চান তাদের জন্য এই পদক্ষেপগুলি অনুসরণ করুন:

1) অ্যান্ড্রয়েড OAuth API এর উত্স কোডটি এখানে ডাউনলোড করুন: https://github.com/kaeppler/signpost

2) "CommonsHttpOAuthProvider" ক্লাস ফাইলটি সন্ধান করুন

3) নীচের হিসাবে এটি পরিবর্তন করুন:

public class CommonsHttpOAuthProvider extends AbstractOAuthProvider {

private static final long serialVersionUID = 1L;

private transient HttpClient httpClient;

public CommonsHttpOAuthProvider(String requestTokenEndpointUrl, String accessTokenEndpointUrl,
        String authorizationWebsiteUrl) {
    super(requestTokenEndpointUrl, accessTokenEndpointUrl, authorizationWebsiteUrl);


    //this.httpClient = new DefaultHttpClient();//Version implemented and that throws the famous "javax.net.ssl.SSLException: Not trusted server certificate" if the certificate is not signed with a CA
    this.httpClient = MySSLSocketFactory.getNewHttpClient();//This will work with all certificates (for testing purposes only)
}

উপরের "মাইএসএসএলস্কটফ্যাক্টরি" গৃহীত উত্তরের উপর ভিত্তি করে। এটি আরও সহজ করার জন্য, এখানে সম্পূর্ণ ক্লাস চলে:

package com.netcomps.oauth_example;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

//http://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https
public class MySSLSocketFactory extends SSLSocketFactory {

    SSLContext sslContext = SSLContext.getInstance("TLS");

public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {

    super(truststore);
    TrustManager tm = new X509TrustManager() {

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

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

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

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

@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
    return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}

@Override
public Socket createSocket() throws IOException {
    return sslContext.getSocketFactory().createSocket();
}



public static HttpClient getNewHttpClient() {

    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);

        SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);

    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}

}

আশা করি এটি কাউকে সাহায্য করবে।


1
প্রশ্নটি ছিল HttpClientএবং এইচটিটিপিএস; গিটহাব প্রকল্প থেকে অ্যান্ড্রয়েডের জন্য ওআউথ নয়।
jwww

3

আমি এটি ব্যবহার করেছি এবং এটি সমস্ত ওএসে আমার জন্য কাজ করে।

/**
 * Disables the SSL certificate checking for new instances of {@link HttpsURLConnection} This has been created to
 * aid testing on a local box, not for use on production.
 */


private static void disableSSLCertificateChecking() {
    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            // Not implemented
        }

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            // Not implemented
        }
    } };

    try {
        SSLContext sc = SSLContext.getInstance("TLS");

        sc.init(null, trustAllCerts, new java.security.SecureRandom());

        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}

হ্যালো @ ইয়েগোর 256, আমি এই কোডটি ব্যবহার করছি তবে এখনও এসএসএল হ্যান্ডশেকের সমস্যা হচ্ছে
ব্যবহারকারী 2028

1

শুধু -Dtrust_all_cert=trueভিএম যুক্তিতে যুক্ত করা উচিত। এই যুক্তি জাভা শংসাপত্রের চেক উপেক্ষা করতে বলে।


4
দয়া করে একাধিক প্রশ্নের একই উত্তর যুক্ত করবেন না । সেরাটির উত্তর দিন এবং বাকীটিকে সদৃশ হিসাবে চিহ্নিত করুন। দেখুন বেশ কয়েকটি প্রশ্নের সদৃশ উত্তর যুক্ত করা কি গ্রহণযোগ্য?
পিটার ফ্রিবার্গ

0

অ্যান্ড্রয়েড ২.১ দর্শনটিতে স্টার্টকম এসএসএল শংসাপত্রগুলির সাথে এখনও লড়াই করা কোনও সংস্থা https://www.startssl.com/certs/ দেখুন এবং সিএইপিএম ডাউনলোড করুন, এখন এমএমবি প্রতিস্থাপনের দেওয়া উত্তরে

`export CLASSPATH=bcprov-jdk16-145.jar
 CERTSTORE=res/raw/mystore.bks
      if [ -a $CERTSTORE ]; then
          rm $CERTSTORE || exit 1
      fi
 keytool \
  -import \
  -v \
  -trustcacerts \
  -alias 0 \
  -file <(openssl x509 -in mycert.pem) \
  -keystore $CERTSTORE \
  -storetype BKS \
  -provider org.bouncycastle.jce.provider.BouncyCastleProvider \
  -providerpath /usr/share/java/bcprov.jar \
  -storepass some-password`

সঙ্গে

 `export CLASSPATH=bcprov-jdk16-145.jar
 CERTSTORE=res/raw/mystore.bks
      if [ -a $CERTSTORE ]; then
          rm $CERTSTORE || exit 1
      fi
 keytool \
  -import \
  -v \
  -trustcacerts \
  -alias 0 \
  -file <(openssl x509 -in ca.pem) \
  -keystore $CERTSTORE \
  -storetype BKS \
  -provider org.bouncycastle.jce.provider.BouncyCastleProvider \
  -providerpath /usr/share/java/bcprov.jar \
  -storepass some-password`

বাক্সের বাইরে কাজ করা উচিত। যথাযথ উত্তরের পরেও আমি একদিন ধরে লড়াই করে যাচ্ছিলাম@ এমএমবি-র যাচ্ছিলাম .. আশা করি এটি কারও পক্ষে সহায়তা করবে ...


0

এই ক্লাস ব্যবহার করুন

public class WCFs
{
    //  https://192.168.30.8/myservice.svc?wsdl
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "192.168.30.8";
private static final String SERVICE = "/myservice.svc?wsdl";
private static String SOAP_ACTION = "http://tempuri.org/iWCFserviceMe/";


public static Thread myMethod(Runnable rp)
{
    String METHOD_NAME = "myMethod";

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

    request.addProperty("Message", "Https WCF Running...");
    return _call(rp,METHOD_NAME, request);
}

protected static HandlerThread _call(final RunProcess rp,final String METHOD_NAME, SoapObject soapReq)
{
    final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    int TimeOut = 5*1000;

    envelope.dotNet = true;
    envelope.bodyOut = soapReq;
    envelope.setOutputSoapObject(soapReq);

    final HttpsTransportSE httpTransport_net = new HttpsTransportSE(URL, 443, SERVICE, TimeOut);

    try
    {
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() // use this section if crt file is handmake
        {
            @Override
            public boolean verify(String hostname, SSLSession session)
            {
                return true;
            }
        });

        KeyStore k = getFromRaw(R.raw.key, "PKCS12", "password");
        ((HttpsServiceConnectionSE) httpTransport_net.getServiceConnection()).setSSLSocketFactory(getSSLSocketFactory(k, "SSL"));


    }
    catch(Exception e){}

    HandlerThread thread = new HandlerThread("wcfTd"+ Generator.getRandomNumber())
    {
        @Override
        public void run()
        {
            Handler h = new Handler(Looper.getMainLooper());
            Object response = null;

            for(int i=0; i<4; i++)
            {
                response = send(envelope, httpTransport_net , METHOD_NAME, null);

                try
                {if(Thread.currentThread().isInterrupted()) return;}catch(Exception e){}

                if(response != null)
                    break;

                ThreadHelper.threadSleep(250);
            }

            if(response != null)
            {
                if(rp != null)
                {
                    rp.setArguments(response.toString());
                    h.post(rp);
                }
            }
            else
            {
                if(Thread.currentThread().isInterrupted())
                    return;

                if(rp != null)
                {
                    rp.setExceptionState(true);
                    h.post(rp);
                }
            }

            ThreadHelper.stopThread(this);
        }
    };

    thread.start();

    return thread;
}


private static Object send(SoapSerializationEnvelope envelope, HttpTransportSE androidHttpTransport, String METHOD_NAME, List<HeaderProperty> headerList)
{
    try
    {
        if(headerList != null)
            androidHttpTransport.call(SOAP_ACTION + METHOD_NAME, envelope, headerList);
        else
            androidHttpTransport.call(SOAP_ACTION + METHOD_NAME, envelope);

        Object res = envelope.getResponse();

        if(res instanceof SoapPrimitive)
            return (SoapPrimitive) envelope.getResponse();
        else if(res instanceof SoapObject)
            return ((SoapObject) envelope.getResponse());
    }
    catch(Exception e)
    {}

    return null;
}

public static KeyStore getFromRaw(@RawRes int id, String algorithm, String filePassword)
{
    try
    {
        InputStream inputStream = ResourceMaster.openRaw(id);
        KeyStore keystore = KeyStore.getInstance(algorithm);
        keystore.load(inputStream, filePassword.toCharArray());
        inputStream.close();

        return keystore;
    }
    catch(Exception e)
    {}

    return null;
}

public static SSLSocketFactory getSSLSocketFactory(KeyStore trustKey, String SSLAlgorithm)
{
    try
    {
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustKey);

        SSLContext context = SSLContext.getInstance(SSLAlgorithm);//"SSL" "TLS"
        context.init(null, tmf.getTrustManagers(), null);

        return context.getSocketFactory();
    }
    catch(Exception e){}

    return null;
}

}


0

এখানে চিত্র বর্ণনা লিখুন

জ্যামারিন অ্যান্ড্রয়েডে একটি এসএসপি ব্যর্থ।

আমি এই সমাধানটি খুঁজে পেয়েছি; আপনি এইচটিটিপিএস লিঙ্কে আঘাত করার আগে এই কোডটি রাখুন

const SslProtocols _Tls12 = (SslProtocols)0x00000C00;
const SecurityProtocolType Tls12 = (SecurityProtocolType)_Tls12;
ServicePointManager.SecurityProtocol = Tls12;

-3

সমস্ত https নিয়ে কাজ করুন

httpClient = new DefaultHttpClient();

SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
    public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

    public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

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

ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, ssf));

2
এই একই থাবাটিতে ইতিমধ্যে আলোচনা করা হয়েছে এবং খারিজ করা হয়েছে ঠিক একই অনিরাপদ অনিরাপদ অ-সমাধানের পুনরাবৃত্তি।
লার্ন

-3

উপরে অনেকগুলি উত্তর রয়েছে তবে আমি তাদের কোনওটিই সঠিকভাবে (আমার সীমিত সময়ের সাথে) কাজ করতে সক্ষম হইনি, সুতরাং একই পরিস্থিতিতে অন্য যে কোনও ব্যক্তির জন্য আপনি নীচের কোডটি চেষ্টা করতে পারেন যা আমার জাভা পরীক্ষার উদ্দেশ্যে পুরোপুরি কাজ করেছে:

    public static HttpClient wrapClient(HttpClient base) {
    try {
        SSLContext ctx = SSLContext.getInstance("TLS");
        X509TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

            public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        ctx.init(null, new TrustManager[]{tm}, null);
        SSLSocketFactory ssf = new SSLSocketFactory(ctx);
        ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        ClientConnectionManager ccm = base.getConnectionManager();
        SchemeRegistry sr = ccm.getSchemeRegistry();
        sr.register(new Scheme("https", ssf, 443));
        return new DefaultHttpClient(ccm, base.getParams());
    } catch (Exception ex) {
        return null;
    }
}

এবং কল করুন:

DefaultHttpClient baseClient = new DefaultHttpClient();
HttpClient httpClient = wrapClient(baseClient );

তথ্যসূত্র: http://tech.chitgoks.com/2011/04/24/how-to-avoid-javax-net-ssl-sslpeerunverifiedexception-peer-not-authenticated-problem- using-apache- httpclient/


ইজেপিকে উদ্ধৃত করার জন্য: "এই থ্রেডে ইতিমধ্যে আলোচনা করা হয়েছে এবং খারিজ করা হয়েছে একই ফ্যালাসিয়াস অনিরাপদ অ-সমাধানের পুনরাবৃত্তি"
jww

-4

কেবল এটি ব্যবহার করুন -

public DefaultHttpClient wrapClient(HttpClient base) {
    try {
        SSLContext ctx = SSLContext.getInstance("TLS");
        X509TrustManager tm = new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

        public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    };
    ctx.init(null, new TrustManager[]{tm}, null);
    SSLSocketFactory ssf = new SSLSocketFactory(ctx);
    ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    ClientConnectionManager ccm = base.getConnectionManager();
    SchemeRegistry sr = ccm.getSchemeRegistry();
    sr.register(new Scheme("https", ssf, 443));
    return new DefaultHttpClient(ccm, base.getParams());
} catch (Exception ex) {
    return null;
}
}

ইজেপিকে উদ্ধৃত করার জন্য: "এই থ্রেডে ইতিমধ্যে আলোচনা করা হয়েছে এবং খারিজ করা হয়েছে একই ফ্যালাসিয়াস অনিরাপদ অ-সমাধানের পুনরাবৃত্তি"
jwww

-5

ড্যানিয়েলের উত্তর ভাল ছিল যদি না আমাকে এই কোডটি পরিবর্তন করতে হত ...

    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    registry.register(new Scheme("https", sf, 443));

    ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

এই কোডে ...

    ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
    SchemeRegistry registry = ccm.getShemeRegistry()
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    registry.register(new Scheme("https", sf, 443));

এটি কাজ পেতে।


5
কিভাবে কাজ করা উচিত? আপনি রেজিস্ট্রি রেফারেন্স আপনি এটি তৈরি করার আগে!
ম্যাথিয়াস বি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.