স্ব-স্বাক্ষরিত শংসাপত্রগুলির সাথে HTTPS সংযোগ গ্রহণ করা


153

আমি HttpClientলিবিটি ব্যবহার করে এইচটিটিপিএস সংযোগগুলি তৈরি করার চেষ্টা করছি , তবে সমস্যাটি হ'ল যেহেতু শংসাপত্রটি অ্যান্ড্রয়েড বিশ্বস্ত শংসাপত্রগুলির সেটে তালিকাভুক্ত ভেরিসাইন , গ্লোবালআইগন প্রভৃতি স্বীকৃত শংসাপত্র কর্তৃপক্ষ (সিএ) দ্বারা স্বাক্ষরিত হয়নি , আমি পেতে থাকি javax.net.ssl.SSLException: Not trusted server certificate

আমি সমাধানগুলি দেখেছি যেখানে আপনি কেবল সমস্ত শংসাপত্র গ্রহণ করেন তবে আমি যদি ব্যবহারকারীকে জিজ্ঞাসা করতে চাই তবে কী হবে?

আমি ব্রাউজারের মতো একটি কথোপকথন পেতে চাই, যা ব্যবহারকারীকে চালিয়ে যেতে বা না চালিয়ে যাওয়ার সিদ্ধান্ত নিতে দিন। আমি ব্রাউজারের মতো একই সার্টিফিকেট স্টোরটি ব্যবহার করতে চাই। কোন ধারনা?


এই স্বীকৃত সমাধানটি আমার জন্য কাজ করেছে- stackoverflow.com/questions/2642777/…
ভেঙ্কটেশ

উত্তর:


171

আপনাকে প্রথমে যা করতে হবে তা হচ্ছে যাচাইয়ের স্তরটি নির্ধারণ করা। এ জাতীয় স্তর এত বেশি নয়:

  • ALLOW_ALL_HOSTNAME_VERIFIER
  • BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
  • STRICT_HOSTNAME_VERIFIER

যদিও পদ্ধতিটি হোস্টনেমভেরিফায়ার () নতুন লাইব্রেরি অ্যাপাচি-র জন্য অপ্রচলিত, তবে অ্যান্ড্রয়েডের সংস্করণে এসডিকে স্বাভাবিক। এবং তাই আমরা এটি গ্রহণ করি ALLOW_ALL_HOSTNAME_VERIFIERএবং পদ্ধতি কারখানায় সেট করি SSLSocketFactory.setHostnameVerifier()

এরপরে, আপনার প্রোটোকলের জন্য https এ আমাদের কারখানা সেট করা দরকার। এটি করার জন্য, কেবল SchemeRegistry.register()পদ্ধতিটি কল করুন ।

তারপরে আপনার DefaultHttpClientসাথে একটি তৈরি করা দরকার SingleClientConnManager। এছাড়াও নীচের কোডটিতে আপনি দেখতে পারেন যে ডিফল্টরূপে ALLOW_ALL_HOSTNAME_VERIFIERপদ্ধতি দ্বারাও আমাদের পতাকা ( ) ব্যবহার করা হবেHttpsURLConnection.setDefaultHostnameVerifier()

নীচে কোড আমার জন্য কাজ করে:

HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

DefaultHttpClient client = new DefaultHttpClient();

SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());

// Set verifier     
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

// Example send http request
final String url = "https://encrypted.google.com/";
HttpPost httpPost = new HttpPost(url);
HttpResponse response = httpClient.execute(httpPost);

6
দুর্ভাগ্যক্রমে আমি এই কোডটি কাজ করতে পারি না, আমি এখনও "বিশ্বস্ত সার্ভার শংসাপত্র নয়" পেয়েছি। এটির কাজ করার জন্য আমাকে কি আরও অতিরিক্ত অনুমতি প্রদান করতে হবে?
Juriy

1
এই কোডটি কেবল সমস্ত শংসাপত্র গ্রহণ করে না? এটি গ্রহণ করার জন্য আমার একটি পপআপ দরকার।
মর্টেন

3
আমি ব্যবহার করছি org.apache.http.conn.ssl.SSLSocketFactoryকেন আমি ব্যবহার করতে চাই javax.net.ssl.HttpsURLConnection??
কেউ সোমবার 20

9
পুরোপুরি শংসাপত্র যাচাইকরণ অক্ষম করার চেয়ে এই কোডটি কীভাবে আরও কার্যকর তা আপনি ব্যাখ্যা করতে পারেন? আমি অ্যান্ড্রয়েডের এসএসএল এপিআইয়ের সাথে পরিচিত নই, তবে এক নজরে এটি সক্রিয় আক্রমণকারীদের বিরুদ্ধে সম্পূর্ণ নিরাপদ বলে মনে হয়।
কোডসইনচাউস

3
আমি সিঙ্গলক্লিয়েন্টকেন ম্যানেজারের পরিবর্তে থ্রেডসএফএফ্লাইড কনট ম্যানেজার ব্যবহার করার পরামর্শ দেব
ফার্ম

124

অ্যান্ড্রয়েড প্ল্যাটফর্ম দ্বারা বিশ্বাসযোগ্য হিসাবে বিবেচিত নয় যা শংসাপত্র কর্তৃপক্ষের সুরক্ষিত সংযোগ অর্জনের জন্য নিম্নলিখিত প্রধান পদক্ষেপগুলির প্রয়োজন।

অনেক ব্যবহারকারীদের অনুরোধ হিসাবে, আমি আমার ব্লগ নিবন্ধ থেকে সর্বাধিক গুরুত্বপূর্ণ অংশগুলি মিরর করেছি :

  1. সমস্ত প্রয়োজনীয় শংসাপত্র (রুট এবং কোনও মধ্যবর্তী সিএ এর) গ্র্যাব করুন
  2. কীটল এবং বাউনিসিস্টল সরবরাহকারীর সাথে একটি কীস্টোর তৈরি করুন এবং শংসাপত্রগুলি আমদানি করুন
  3. আপনার অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিতে কীস্টোরটি লোড করুন এবং সুরক্ষিত সংযোগগুলির জন্য এটি ব্যবহার করুন (আমি স্ট্যান্ডার্ডের পরিবর্তে অ্যাপাচি এইচটিপিপিলেট ব্যবহার করার পরামর্শ দিচ্ছি java.net.ssl.HttpsURLConnection(বুঝতে আরও সহজ, আরও পারফরম্যান্ট))

শংসাপত্রগুলি ধরুন

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

কীস্টোরটি তৈরি করুন

বাউনসিস্টল সরবরাহকারীটি ডাউনলোড করুন এবং এটি একটি পরিচিত স্থানে সংরক্ষণ করুন। এছাড়াও নিশ্চিত করুন যে আপনি কীটল কমান্ডটি চালু করতে পারেন (সাধারণত আপনার জেআরই ইনস্টলেশনের বিন ফোল্ডারের নীচে অবস্থিত)।

এখন প্রাপ্ত শংসাপত্রগুলি (শেষের বিন্দু শংসাপত্রটি আমদানি করবেন না) বাউন্সিস্টল ফর্ম্যাটেড কীস্টোরগুলিতে আমদানি করুন।

আমি এটি পরীক্ষা করিনি, তবে আমি মনে করি শংসাপত্রগুলি আমদানির ক্রমটি গুরুত্বপূর্ণ। এর অর্থ, প্রথমে নিম্নতম মধ্যবর্তী সিএ শংসাপত্রটি আমদানি করুন এবং তারপরে রুট সিএ শংসাপত্রটি পর্যন্ত।

নিম্নলিখিত কমান্ডের সাথে একটি নতুন কীস্টোর (ইতিমধ্যে উপস্থিত না থাকলে) পাসওয়ার্ড সহ মাইক্রিট তৈরি হবে এবং মধ্যবর্তী সিএ শংসাপত্রটি আমদানি করা হবে। আমি বাউনসিস্টল সরবরাহকারীর সংজ্ঞাও দিয়েছি, যেখানে এটি আমার ফাইল সিস্টেম এবং কীস্টোর ফর্ম্যাটে পাওয়া যাবে। শৃঙ্খলে প্রতিটি শংসাপত্রের জন্য এই আদেশটি কার্যকর করুন।

keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

কীস্টোরে শংসাপত্রগুলি সঠিকভাবে আমদানি করা হয়েছিল কিনা তা যাচাই করুন:

keytool -list -keystore "res/raw/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

পুরো চেইন আউটপুট করা উচিত:

RootCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93
IntermediateCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43

এখন আপনি নীচে আপনার অ্যান্ড্রয়েড অ্যাপ্লিকেশনে একটি কাঁচা সংস্থান হিসাবে কীস্টোরটি অনুলিপি করতে পারেন res/raw/

আপনার অ্যাপ্লিকেশনটিতে কীস্টোরটি ব্যবহার করুন

সবার আগে আমাদের একটি কাস্টম অ্যাপাচি এইচটিটিপিপ্লায়েন্ট তৈরি করতে হবে যা এইচটিটিপিএস সংযোগের জন্য আমাদের কীস্টোর ব্যবহার করে:

import org.apache.http.*

public class MyHttpClient extends DefaultHttpClient {

    final Context context;

    public MyHttpClient(Context context) {
        this.context = context;
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        // Register for port 443 our SSLSocketFactory with our keystore
        // to the ConnectionManager
        registry.register(new Scheme("https", newSslSocketFactory(), 443));
        return new SingleClientConnManager(getParams(), registry);
    }

    private SSLSocketFactory newSslSocketFactory() {
        try {
            // Get an instance of the Bouncy Castle KeyStore format
            KeyStore trusted = KeyStore.getInstance("BKS");
            // Get the raw resource, which contains the keystore with
            // your trusted certificates (root and any intermediate certs)
            InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
            try {
                // Initialize the keystore with the provided trusted certificates
                // Also provide the password of the keystore
                trusted.load(in, "mysecret".toCharArray());
            } finally {
                in.close();
            }
            // Pass the keystore to the SSLSocketFactory. The factory is responsible
            // for the verification of the server certificate.
            SSLSocketFactory sf = new SSLSocketFactory(trusted);
            // Hostname verification from certificate
            // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
            sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
            return sf;
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

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

// Instantiate the custom HttpClient
DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpGet get = new HttpGet("https://www.mydomain.ch/rest/contacts/23");
// Execute the GET call and obtain the response
HttpResponse getResponse = client.execute(get);
HttpEntity responseEntity = getResponse.getEntity();

এটাই ;)


8
এটি কেবল আপনার অ্যাপ্লিকেশনটি শিপিংয়ের আগে শংসাপত্র পাওয়ার জন্য কার্যকর। ব্যবহারকারীদের নিজস্ব শংসাপত্র গ্রহণ করতে সত্যই সহায়তা করে না। আপনার অ্যাপ্লিকেশনটির জন্য
ফাজি

হাই সবাই কি আমাকে উপরের বাস্তবায়নের জন্য ট্রস্টস্টোর সহ কীস্টোরের বৈধতা প্রক্রিয়া বলতে পারে ??? অগ্রিম ধন্যবাদ ..
andriod_test

এটি ঠিকঠাক কাজ করেছে .. তবে আমি যখন সার্ভারে শংসাপত্রটি রিকি করি তখন আমি একটি সমস্যার মুখোমুখি হয়েছি। এটি অদ্ভুত বলে মনে হচ্ছে যে আমি যখনই আমার সার্ভারে শংসাপত্রটি আপডেট করি তখন ক্লায়েন্টের সাইড স্টোরটিও আপডেট করা উচিত। আরও ভাল উপায় থাকতে হবে: |
বিপিএন

GR8 উত্তর, আমি সিঙ্গলক্লিয়েন্টকেন ম্যানেজারের পরিবর্তে ThreadSafeClientConnManager ব্যবহারের পরামর্শ দেব
ফার্ম

আমি যোগ করেছি /res/raw/mykeystore.bks, যদিও এর উল্লেখটি সমাধান করতে অক্ষম। কীভাবে সমাধান করব?
uniruddh

16

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

শংসাপত্রের *.crtফাইলটি /res/rawএমনভাবে রাখুন যাতে এটি উপলব্ধ থাকেR.raw.*

এমন শংসাপত্রটি ব্যবহার করে সকেট ফ্যাক্টরি থাকবে HTTPClientবা HttpsURLConnectionতা পেতে ক্লাসের নীচে ব্যবহার করুন :

package com.example.customssl;

import android.content.Context;
import org.apache.http.client.HttpClient;
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.AllowAllHostnameVerifier;
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 javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;

public class CustomCAHttpsProvider {

    /**
     * Creates a {@link org.apache.http.client.HttpClient} which is configured to work with a custom authority
     * certificate.
     *
     * @param context       Application Context
     * @param certRawResId  R.raw.id of certificate file (*.crt). Should be stored in /res/raw.
     * @param allowAllHosts If true then client will not check server against host names of certificate.
     * @return Http Client.
     * @throws Exception If there is an error initializing the client.
     */
    public static HttpClient getHttpClient(Context context, int certRawResId, boolean allowAllHosts) throws Exception {


        // build key store with ca certificate
        KeyStore keyStore = buildKeyStore(context, certRawResId);

        // init ssl socket factory with key store
        SSLSocketFactory sslSocketFactory = new SSLSocketFactory(keyStore);

        // skip hostname security check if specified
        if (allowAllHosts) {
            sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());
        }

        // basic http params for client
        HttpParams params = new BasicHttpParams();

        // normal scheme registry with our ssl socket factory for "https"
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));

        // create connection manager
        ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);

        // create http client
        return new DefaultHttpClient(cm, params);
    }

    /**
     * Creates a {@link javax.net.ssl.HttpsURLConnection} which is configured to work with a custom authority
     * certificate.
     *
     * @param urlString     remote url string.
     * @param context       Application Context
     * @param certRawResId  R.raw.id of certificate file (*.crt). Should be stored in /res/raw.
     * @param allowAllHosts If true then client will not check server against host names of certificate.
     * @return Http url connection.
     * @throws Exception If there is an error initializing the connection.
     */
    public static HttpsURLConnection getHttpsUrlConnection(String urlString, Context context, int certRawResId,
                                                           boolean allowAllHosts) throws Exception {

        // build key store with ca certificate
        KeyStore keyStore = buildKeyStore(context, certRawResId);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);

        // Create a connection from url
        URL url = new URL(urlString);
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());

        // skip hostname security check if specified
        if (allowAllHosts) {
            urlConnection.setHostnameVerifier(new AllowAllHostnameVerifier());
        }

        return urlConnection;
    }

    private static KeyStore buildKeyStore(Context context, int certRawResId) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
        // init a default key store
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);

        // read and add certificate authority
        Certificate cert = readCert(context, certRawResId);
        keyStore.setCertificateEntry("ca", cert);

        return keyStore;
    }

    private static Certificate readCert(Context context, int certResourceId) throws CertificateException, IOException {

        // read certificate resource
        InputStream caInput = context.getResources().openRawResource(certResourceId);

        Certificate ca;
        try {
            // generate a certificate
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            ca = cf.generateCertificate(caInput);
        } finally {
            caInput.close();
        }

        return ca;
    }

}

গুরুত্বপূর্ণ দিক:

  1. Certificateবস্তুগুলি .crtফাইল থেকে উত্পন্ন হয় ।
  2. একটি ডিফল্ট KeyStoreতৈরি করা হয়।
  3. keyStore.setCertificateEntry("ca", cert)উপন্যাস "সিএ" এর অধীনে কী স্টোরটিতে শংসাপত্র যুক্ত করা হচ্ছে। আপনি আরও শংসাপত্র যুক্ত করার জন্য কোডটি সংশোধন করুন (মধ্যবর্তী সিএ ইত্যাদি)।
  4. মূল উদ্দেশ্য হ'ল একটি উত্পন্ন করা SSLSocketFactoryযা এরপরে HTTPClientবা দ্বারা ব্যবহার করা যেতে পারে HttpsURLConnection
  5. SSLSocketFactory আরও কনফিগার করা যায়, উদাহরণস্বরূপ হোস্টের নাম যাচাইকরণ এড়িয়ে যাওয়া ইত্যাদি

এখানে আরও তথ্য: http://developer.android.com/training/articles/security-ssl.html


আমি কোথায় .crtফাইল পেতে পারি ? একটি সার্ভার থেকে ডাউনলোড করতে পারি ?
zionpi

@ জিয়নপিআই শংসাপত্রের ফাইলটি আপনি যে টিএলএস সক্ষম সার্ভারের সাথে সংযোগ করছেন তার দ্বারা ব্যবহৃত হবে।
এসডি

ধন্যবাদ! এটি এত সহজ ছিল!
কাপিল থাদানি

@ এসডি কীভাবে আমি .crt এর পরিবর্তে .P12 ফাইলটি ব্যবহার করতে পারি?
রাকেশ আর নায়ার

আমি একটি অনুরূপ সন্দেহ ঠান্ডা আপনাকে সাহায্য করবে দয়া stackoverflow.com/questions/57389622/...
StezPet

8

Https ব্যবহার করে আমার অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিকে আমার আরএসএফুল সার্ভিসে সংযুক্ত করার চেষ্টা করে হতাশ হয়ে পড়েছিলাম। এছাড়াও আমি সমস্ত উত্তর সম্পর্কে সামান্য বিরক্ত হয়েছিলাম যা সার্টিফিকেট চেকিং পুরোপুরি অক্ষম করার পরামর্শ দেয়। আপনি যদি তা করেন তবে https এর বিন্দু কী?

কিছুক্ষণ এই বিষয় সম্পর্কে গুগল করার পরে, অবশেষে আমি এই সমাধানটি খুঁজে পেয়েছি যেখানে কেবলমাত্র অ্যান্ড্রয়েড এপিআই, বাহ্যিক জারগুলির প্রয়োজন হয় না। অ্যান্ড্রু স্মিথকে ধন্যবাদ, যিনি এটি জুলাই, 2014 এ পোস্ট করেছিলেন

 /**
 * Set up a connection to myservice.domain using HTTPS. An entire function
 * is needed to do this because myservice.domain has a self-signed certificate.
 * 
 * The caller of the function would do something like:
 * HttpsURLConnection urlConnection = setUpHttpsConnection("https://littlesvr.ca");
 * InputStream in = urlConnection.getInputStream();
 * And read from that "in" as usual in Java
 * 
 * Based on code from:
 * https://developer.android.com/training/articles/security-ssl.html#SelfSigned
 */
public static HttpsURLConnection setUpHttpsConnection(String urlString)
{
    try
    {
        // Load CAs from an InputStream
        // (could be from a resource or ByteArrayInputStream or ...)
        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        // My CRT file that I put in the assets folder
        // I got this file by following these steps:
        // * Go to https://littlesvr.ca using Firefox
        // * Click the padlock/More/Security/View Certificate/Details/Export
        // * Saved the file as littlesvr.crt (type X.509 Certificate (PEM))
        // The MainActivity.context is declared as:
        // public static Context context;
        // And initialized in MainActivity.onCreate() as:
        // MainActivity.context = getApplicationContext();
        InputStream caInput = new BufferedInputStream(MainActivity.context.getAssets().open("littlesvr.crt"));
        Certificate ca = cf.generateCertificate(caInput);
        System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());

        // Create a KeyStore containing our trusted CAs
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);

        // Tell the URLConnection to use a SocketFactory from our SSLContext
        URL url = new URL(urlString);
        HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
        urlConnection.setSSLSocketFactory(context.getSocketFactory());

        return urlConnection;
    }
    catch (Exception ex)
    {
        Log.e(TAG, "Failed to establish SSL connection to server: " + ex.toString());
        return null;
    }
}

এটি আমার মকআপ অ্যাপের জন্য দুর্দান্ত কাজ করেছে।


X509 প্রমাণ করুন কোনটি জাভা বা জাভ্যাক্স আমদানি করা উচিত?
সিদ্ধার্থ

আমি আমদানি করেছিimport java.security.cert.X509Certificate;
গনজালো ফার্নান্দেজ

এই জন্য ধন্যবাদ। এটি সত্যিই কাজ এবং সহজ
অনুরাধে দিলশান

6

শীর্ষের উত্তরটি আমার পক্ষে কাজ করে না। কিছু তদন্তের পরে আমি "অ্যান্ড্রয়েড বিকাশকারী" সম্পর্কিত প্রয়োজনীয় তথ্য খুঁজে পেয়েছি: https://developer.android.com/training/articles/security-ssl.html#Slp সাইনড

এক্স 509 ট্রাস্টম্যানেজারের একটি খালি বাস্তবায়ন তৈরিটি কৌশলটি করেছে:

private static class MyTrustManager implements 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;
    }

}

...

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
try
{
    // Create an SSLContext that uses our TrustManager
    SSLContext context = SSLContext.getInstance("TLS");
    TrustManager[] tmlist = {new MyTrustManager()};
    context.init(null, tmlist, null);
    conn.setSSLSocketFactory(context.getSocketFactory());
}
catch (NoSuchAlgorithmException e)
{
    throw new IOException(e);
} catch (KeyManagementException e)
{
    throw new IOException(e);
}
conn.setRequestMethod("GET");
int rcode = conn.getResponseCode();

দয়া করে সচেতন হন যে টুস্টম্যানেজারের এই খালি বাস্তবায়ন কেবল একটি উদাহরণ এবং উত্পাদনশীল পরিবেশে এটি ব্যবহার করা একটি মারাত্মক সুরক্ষা হুমকির কারণ হতে পারে!


1
ঠিক এফআইআই - আইডিকি যদি সেই সময়ে এমন হত তবে তারা এখন এই পদ্ধতিকে
দৃ

6

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

এবং এছাড়াও, কখনও এসএসএল শংসাপত্রের দরকার নেই (কখনও নেই !!!)।

এসএসএল শংসাপত্রগুলি নাকচ করা, SSL- এর উদ্দেশ্যগুলির সম্পূর্ণ পরিপন্থী, যা সুরক্ষা প্রচার করে । এসএসএল ব্যবহার করার কোনও ধারণা নেই, আপনি যদি এসএসএল থেকে আসা সমস্ত শংসাপত্রগুলি বোমা করার পরিকল্পনা করছেন। আরও ভাল সমাধান হ'ল, এসএসএল না ব্যবহার করা বা আরও ভাল সমাধান TrustManagerহ'ল আপনার অ্যাপ + এ এইচটিটিপি / এইচটিটিপিএস সংযোগের জন্য অ্যান্ড্রয়েড ভোলি ব্যবহার করে একটি কাস্টম তৈরি করা হবে ।

এখানে একটি ব্যাপার সারকথা মৌলিক LoginApp সঙ্গে যা আমি সৃষ্টি, HTTPS দ্বারা সংযোগ, সার্ভার সাইড উপর একটি স্ব-স্বাক্ষরিত সার্টিফিকেট, অ্যাপ গ্রহণ ব্যবহার অনুষ্ঠানে যোগ দেন।

আপনার সার্ভারে সেট আপ করার জন্য স্ব-স্বাক্ষরিত এসএসএল শংসাপত্র তৈরি করার জন্য এবং আপনার অ্যাপে শংসাপত্রটি ব্যবহার করার জন্য এখানে সহায়তা করতে পারে এমন আরও একটি গিস্টখুব গুরুত্বপূর্ণ: আপনার অবশ্যই অ্যান্ড্রয়েড প্রকল্পের "কাঁচা" ডিরেক্টরিতে উপরের স্ক্রিপ্ট দ্বারা উত্পন্ন .crt ফাইলটি অনুলিপি করতে হবে।


হ্যালো ইভান, আমি কখনই এসএসএল শংসাপত্র নিয়ে কাজ করি নি। আপনি কি কিছুটা বিস্তৃত করার যত্ন নেবেন, আমি কীভাবে .crt ফাইল পাব?
jlively

হাই জিভলি! আমি দেখি. হ্যা অবশ্যই. তবে প্রথমে, আপনি উপরে উল্লিখিত দ্বিতীয় গিস্টটি একবার খেয়াল করতে আপত্তি করবেন? আমি এই গিস্টটিতে দুটি ফাইল রেখেছি: একটি হ'ল স্ক্রিপ্ট দ্বারা ব্যবহৃত ফাইল এবং অন্যটি হ'ল স্ক্রিপ্ট নিজেই, যে ফাইলটি পড়ার জন্য "ওপেনসেল" বাইনারি ব্যবহার করে এবং তারপরে, এসএসএল শংসাপত্রযুক্ত ফাইলটি তৈরি করে ( .crt)। আপনি পুরো বিষয়টি বুঝতে সক্ষম হলে আমাকে জানান know শুভেচ্ছা :)।
ivanleoncz

হুঁ হ্যাঁ আমি এই 2 টি গিস্টগুলি দেখেছি, তবে আমি কীভাবে এগুলি ব্যবহার করব তা আমি সত্যি বুঝতে পারি না?
jlively

4

এই সমস্যাটি এড়াতে কীভাবে আপনি আপনার কীস্টোরগুলিতে অতিরিক্ত শংসাপত্র যুক্ত করতে পারেন তা এখানে: এইচটিটিপিএস-এর মাধ্যমে এইচটিপিপিপ্লায়েন্ট ব্যবহার করে সমস্ত শংসাপত্রের উপর বিশ্বাস রাখা

এটি ব্যবহারকারীকে আপনার অনুরোধের অনুরোধ জানাবে না, তবে এটির কম সম্ভাবনা তৈরি হবে যে ব্যবহারকারী কোনও "বিশ্বাসযোগ্য সার্ভার শংসাপত্র নয়" ত্রুটিতে চলে যাবে।


কেবল পরীক্ষার উদ্দেশ্যে, আপনি এই কৌশলটি দিয়ে প্লে স্টোরে একটি অ্যাপ প্রকাশ করতে পারবেন না কারণ এটি প্রত্যাখ্যান করা হবে
অ্যারিয়েল

3

এসএসএল শংসাপত্র তৈরির সহজ উপায়

ফায়ারফক্স খুলুন (আমি মনে করি এটি ক্রোমের সাথেও সম্ভব, তবে এফএফ দিয়ে এটি আমার পক্ষে সহজ)

স্ব-স্বাক্ষরিত SSL শংসাপত্র সহ আপনার বিকাশ সাইটটি দেখুন।

শংসাপত্রটিতে ক্লিক করুন (সাইটের নামের পাশে)

"আরও তথ্য" ক্লিক করুন

"শংসাপত্র দেখুন" ক্লিক করুন

"বিশদ" ক্লিক করুন

"রফতানি ..." এ ক্লিক করুন

"X.509 শংসাপত্র whith চেইন (PEM)" চয়ন করুন, এটি সংরক্ষণ করতে ফোল্ডার এবং নাম নির্বাচন করুন এবং "সংরক্ষণ করুন" ক্লিক করুন

কমান্ড লাইনে গিয়ে আপনি যে ডিরেক্টরিটি পেম ফাইল ডাউনলোড করেছেন সেখানে যান এবং "ওপেনসেল এক্স509 -ইনফর্ম পিইএম-আউটফর্ম ডিএম-ইন .pem -out .crt" চালনা করুন

আপনার অ্যান্ড্রয়েড ডিভাইসের ভিতরে / এসডিকার্ড ফোল্ডারের মূলটিতে .crt ফাইলটি অনুলিপি করুন আপনার অ্যান্ড্রয়েড ডিভাইসের অভ্যন্তরে, সেটিংস> সুরক্ষা> সঞ্চয়স্থান থেকে ইনস্টল করুন।

এটি শংসাপত্রটি সনাক্ত করে এবং আপনাকে এটি ডিভাইসে যুক্ত করতে দেয় আপনার বিকাশ সাইটে ব্রাউজ করুন।

প্রথমবার আপনাকে সুরক্ষা ব্যতিক্রমটি নিশ্চিত করতে বলা উচিত। এখানেই শেষ.

শংসাপত্রটি আপনার অ্যান্ড্রয়েডে ইনস্টল হওয়া যে কোনও ব্রাউজারের সাথে কাজ করা উচিত (ব্রাউজার, ক্রোম, অপেরা, ডলফিন ...)

মনে রাখবেন যে আপনি যদি কোনও ভিন্ন ডোমেন থেকে স্ট্যাটিক ফাইলগুলি পরিবেশন করে থাকেন (আমরা সকলেই পৃষ্ঠার গতি বিচ করছি) আপনাকে সেই ডোমেনের শংসাপত্র যুক্ত করতে হবে।


2

অ্যান্ড্রয়েডে নির্দিষ্ট শংসাপত্রের উপর ভরসা রাখতে আমি ছোট গ্রন্থাগার ssl-utils-android লিখেছিলাম ।

সম্পদ ডিরেক্টরি থেকে ফাইলের নাম দিয়ে আপনি কেবল কোনও শংসাপত্র লোড করতে পারেন।

ব্যবহার:

OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());

1

এসডিকে ১ of, রিলিজ ৪.১.২ কে লক্ষ্য করে এই উন্নতিগুলির কোনওটিই আমার বিকাশ প্ল্যাটফর্মের জন্য কাজ করেনি, সুতরাং আমি একটি কাজের সন্ধান পেয়েছি।

আমার অ্যাপ্লিকেশন " http://www.example.com/page.php?data=somedata " ব্যবহার করে সার্ভারে ডেটা সঞ্চয় করে

সম্প্রতি পেজ.এফপি " https://www.secure-example.com/page.php " এ সরানো হয়েছে এবং আমি "javax.net.ssl.SSLException: বিশ্বস্ত সার্ভার শংসাপত্র নয়" পেয়ে চলেছি।

কেবলমাত্র একটি পৃষ্ঠার জন্য সমস্ত শংসাপত্র গ্রহণের পরিবর্তে, এই গাইডটি দিয়ে শুরু করে আমার নিজের পৃষ্ঠা.php " http://www.example.com/page.php " এ প্রকাশিত সমস্যাটি সমাধান করেছি

<?php

caronte ("https://www.secure-example.com/page.php");

function caronte($url) {
    // build curl request
    $ch = curl_init();
    foreach ($_POST as $a => $b) {
        $post[htmlentities($a)]=htmlentities($b);
    }
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($post));

    // receive server response ...
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $server_output = curl_exec ($ch);
    curl_close ($ch);

    echo $server_output;
}

?>

1

19 শে জানুয়ারী, 2020 স্ব স্বাক্ষরিত শংসাপত্র ইস্যু ফিক্স:

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

কোটলিন কোড

  private fun disableSSLCertificateChecking() {
        val hostnameVerifier = object: HostnameVerifier {
            override fun verify(s:String, sslSession: SSLSession):Boolean {
                return true
            }
        }
        val trustAllCerts = arrayOf<TrustManager>(object: X509TrustManager {
            override fun getAcceptedIssuers(): Array<X509Certificate> {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }

            //val acceptedIssuers:Array<X509Certificate> = null
            @Throws(CertificateException::class)
            override fun checkClientTrusted(arg0:Array<X509Certificate>, arg1:String) {// Not implemented
            }
            @Throws(CertificateException::class)
            override fun checkServerTrusted(arg0:Array<X509Certificate>, arg1:String) {// Not implemented
            }
        })
        try
        {
            val sc = SSLContext.getInstance("TLS")
            sc.init(null, trustAllCerts, java.security.SecureRandom())
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory())
            HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier)
        }
        catch (e: KeyManagementException) {
            e.printStackTrace()
        }
        catch (e: NoSuchAlgorithmException) {
            e.printStackTrace()
        }
    }

0

হতে পারে এটি সহায়ক হবে ... এটি স্ব-স্বাক্ষরিত শংসাপত্রগুলি ব্যবহার করে জাভা ক্লায়েন্টদের সাথে কাজ করে (শংসাপত্রের কোনও চেক নেই)। সাবধানতা অবলম্বন করুন এবং এটি কেবল উন্নয়নের ক্ষেত্রে ব্যবহার করুন কারণ এটি মোটেই নিরাপদ নয় !!

অ্যাপাচি এইচটিটিপিপ্লায়েন্ট ৪.০ এ কীভাবে SSL শংসাপত্রের ত্রুটি উপেক্ষা করবেন

আশা করি এটি অ্যান্ড্রয়েডে কাজ করবে কেবল এইচটিটিপি ক্লায়েন্ট লাইব্রেরি যুক্ত করবে ... শুভকামনা !!


1
না এটি অ্যান্ড্রয়েডে কাজ করে না কারণ এটি
হ্রাসপ্রাপ্ত

0

এসএনআই (সার্ভারের নাম সনাক্তকরণ) ইনএ, এনড্রয়েড ২.x সমর্থনের অভাবের ফলে এটি সমস্যা is আমি নীচের প্রশ্নটি না আসা পর্যন্ত আমি এই সমস্যাটির সাথে এক সপ্তাহ ধরে লড়াই করে যাচ্ছিলাম, যা কেবল সমস্যার ভাল পটভূমিই দেয় না তবে কোনও সুরক্ষা গর্ত ছাড়াই একটি কার্যকরী এবং কার্যকর সমাধান সরবরাহ করে।

অ্যান্ড্রয়েড ২.৩-তে 'পিয়ার শংসাপত্রের ত্রুটি নেই' তবে 4-এ নয়

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