Android подключается к серверу с подписанным сертификатом

РЕДАКТИРОВАНИЕ: «Код ниже работает нормально, без ошибок, без исключений»

Мне известно о большом количестве вопросов по этой теме, а также о многих блогах, которые вызывает в Google. Я прочитал их и сумел придумать, что я собираюсь объяснить. Мое сомнение заключается вмой подход правильный? Есть ли у него побочные эффекты?И еще один вопрос, который лучше задать, когда я объясняю свой метод.

Я основал этот подход, следуя этомуAndroid.Developres учебник.

 System.setProperty("jsse.enableSNIExtension", "false");  
 //Java 7 introduced SNI (enabled by default). The server I use is
 // misconfigured I suppose and
 // it sends an "Unrecognized Name" warning in the SSL handshake
 // which breaks my web service.

// Load CA from an InputStream (CA would be saved in Raw file,
// and loaded as a raw resource)
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    InputStream caInput = new BufferedInputStream(new FileInputStream("PATH_TO_CERT.crt"));

    Certificate ca;
    try {
        ca = cf.generateCertificate(caInput);
    } finally {
        caInput.close();
    }

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

 // Create all-trusting host name verifier 
    //  to avoid the following :
    //   java.security.cert.CertificateException: No name matching
    // This is because Java by default verifies that the certificate CN (Common Name) is
   // the same as host name in the URL. If they are not, the web service client fails.

     HostnameVerifier allHostsValid = new HostnameVerifier() {
        @Override
        public boolean verify(String arg0, SSLSession arg1) {
            return true;
        }
    };

    //Install it
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);


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

    try {

        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setRequestMethod("GET");

        urlConnection.connect();

        switch(urlConnection.getResponseCode()){
        case 401:


            BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getErrorStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line+"\n");
            }
            br.close();

            System.out.println( sb.toString());

        }



    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }



}

Вот другой мой вопрос, в следующей строке:

InputStream caInput = new BufferedInputStream(new FileInputStream("PATH_TO_CERT.crt"));

Вы видите, что метод вынуждает меня предварительно загрузить сертификат.crt в файл raw внутри папки res. Есть ли способ (я посмотрел, но нашел 0 ответов), чтобы подключиться к серверу и загрузить указанный сертификат.crt и сохранить его в личной папке, недоступной пользователю?

Ответы на вопрос(0)

Ваш ответ на вопрос