2015-12-31 1 views
9

С помощью этой сетевой библиотеки:Как использовать самоподписанный SSL в сетевой библиотеке Android (ION)?

https://github.com/koush/ion

В текущем состоянии развития, я хотел бы использовать самоподписанный SSL сертификат

Библиотеки форум имеет некоторое обсуждение:

https://github.com/koush/ion/issues/3

Ion ion = Ion.getDefault(c); 
    ion.configure().createSSLContext("TLS"); 
    ion.getHttpClient().getSSLSocketMiddleware().setSSLContext(sslContext); 
    ion.getHttpClient().getSSLSocketMiddleware().setTrustManagers(trustManagers); 

После некоторых исследований я захватил crt a го получения SSLContext и TrustManager, проблема в том, что до сих пор вернуться за исключением

javax.net.ssl.SSLException 
Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 

Вот моя попытка:

try { 
     CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
     InputStream caInput = getResources().openRawResource(R.raw.load); 
     Certificate ca; 
     try { 
      ca = cf.generateCertificate(caInput); 
      //System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); 
     } finally { 
      caInput.close(); 
     } 

     String keyStoreType = KeyStore.getDefaultType(); 
     KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
     keyStore.load(null, null); 
     keyStore.setCertificateEntry("ca", ca); 

     String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
     tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
     tmf.init(keyStore); 

     ssl_context = SSLContext.getInstance("TLS"); 
     ssl_context.init(null, tmf.getTrustManagers(), null); 
    } catch (Exception e) { 
     Log.d("test1", "A: " + e); 
    } 

    Ion.getDefault(this).getHttpClient().getSSLSocketMiddleware().setTrustManagers(tmf.getTrustManagers()); 
    Ion.getDefault(this).getHttpClient().getSSLSocketMiddleware().setSSLContext(ssl_context); 

    //test SSL 
    Ion.getDefault(this).with(this) 
      .load("https://na2b.no-ip.com/dragonair/can_app/api/media_list.php") 
      .asJsonObject() 
      .setCallback(new FutureCallback<JsonObject>() { 
       @Override 
       public void onCompleted(Exception e, JsonObject result) { 
        if (e != null) { 
         Log.d("test1", "B: " + e); 
        } else { 
         Log.d("test1", "result" + result); 
        } 
       } 
      }); 

уведомление о том, что исключение в B: часть так, что означает TrustManager и SSLContext должны правильно построить, как это исправить?

Спасибо за помощь.

+1

Я сделал это будет okhttp, посмотрев @ http://developer.android.com/training/articles/security-ssl. HTML. посмотрите, помогает ли он смотреть на документы. – Raghunandan

+1

Для использования с самоподписанным сертификатом, пожалуйста, прочитайте мой ответ по адресу http://stackoverflow.com/questions/32154115/android-volley-self-signed-https-trust-anchor-for-certification-path-not-found/ 32219177? S = 0 | 3.1941 # 32219177 или http://stackoverflow.com/questions/32969952/android-to-server-communication-using-ssl-with-bouncy-castle/32980130?s=0|3.2268#32980130 – BNK

+1

@BNK, спасибо за совет, похоже, не может переопределить настройки сетевой библиотеки – user3538235

ответ

7

Для вашей проблемы, ИМО, вы можете обратиться к моему следующему образцу кода. Я тестировал свой веб-сервис (Asp.Net WebAPI). Надеюсь, поможет!Выход

public class MainActivity extends AppCompatActivity { 

    private Context mContext = this; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     try { 
      CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
      // cert file stored in \app\src\main\res\raw 
      InputStream caInput = getResources().openRawResource(R.raw.your_cert); 

      Certificate ca = cf.generateCertificate(caInput); 
      caInput.close(); 

      KeyStore keyStore = KeyStore.getInstance("BKS"); 
      keyStore.load(null, null); 
      keyStore.setCertificateEntry("ca", ca); 

      String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
      TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
      tmf.init(keyStore); 

      TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers()); 

      SSLContext sslContext = SSLContext.getInstance("TLS"); 
      sslContext.init(null, wrappedTrustManagers, null); 

      AsyncSSLSocketMiddleware sslMiddleWare = Ion.getDefault(mContext).getHttpClient().getSSLSocketMiddleware(); 
      sslMiddleWare.setTrustManagers(wrappedTrustManagers); 
      sslMiddleWare.setHostnameVerifier(getHostnameVerifier()); 
      sslMiddleWare.setSSLContext(sslContext); 

      // Post application/x-www-form-urlencoded and read a String 
      Ion.with(mContext) 
        .load("https://yourserver/token") 
        .setBodyParameter("grant_type", "password") 
        .setBodyParameter("username", "bnk") 
        .setBodyParameter("password", "bnk123456789") 
        .asString() 
        .setCallback(new FutureCallback<String>() { 
         @Override 
         public void onCompleted(Exception e, String result) { 
          if (result != null) { 
           Log.i("ionSample", result); 
          } else if (e != null) { 
           e.printStackTrace(); 
          } 
         } 
        }); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    private HostnameVerifier getHostnameVerifier() { 
     return new HostnameVerifier() { 
      @Override 
      public boolean verify(String hostname, SSLSession session) { 
       return true; 
       // or the following: 
       // HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier(); 
       // return hv.verify("www.yourserver.com", session); 
      } 
     }; 
    } 

    private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) { 
     final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0]; 
     return new TrustManager[]{ 
       new X509TrustManager() { 
        public X509Certificate[] getAcceptedIssuers() { 
         return originalTrustManager.getAcceptedIssuers(); 
        } 

        public void checkClientTrusted(X509Certificate[] certs, String authType) { 
         try { 
          if (certs != null && certs.length > 0){ 
           certs[0].checkValidity(); 
          } else { 
           originalTrustManager.checkClientTrusted(certs, authType); 
          } 
         } catch (CertificateException e) { 
          Log.w("checkClientTrusted", e.toString()); 
         } 
        } 

        public void checkServerTrusted(X509Certificate[] certs, String authType) { 
         try { 
          if (certs != null && certs.length > 0){ 
           certs[0].checkValidity(); 
          } else { 
           originalTrustManager.checkServerTrusted(certs, authType); 
          } 
         } catch (CertificateException e) { 
          Log.w("checkServerTrusted", e.toString()); 
         } 
        } 
       } 
     }; 
    } 
} 

Logcat:

I/ionSample: {"access_token":"oS1SHxck8TzidTL...P-_6VFjRlDsjF9_A0JONu59rzYOVQV...ka78pHSvRPB5YrrBlHsF562Ay__Jd0MDfpOB0SRML2N8O3XPZK8woV4vjASzfGEzi7KJMmY8pkM_-P9ohHhWPD3PtgRahiqTUSapdpg6n197uJxdQWyU","token_type":"bearer","expires_in":2591999,"userName":"bnk",".issued":"Wed, 06 Jan 2016 06:26:45 GMT",".expires":"Fri, 05 Feb 2016 06:26:45 GMT"} 
+1

Спасибо за отличный ответ. один последний вопрос, если есть библиотека изображений, например. Пикассо, который захватывает https-образ, использует ли он SSL? приведенный выше код для использования сети только в ION? – user3538235

+1

Хороший комментарий! Я еще не пробовал с Picasso, однако, я думаю, что он может использоваться как следующий «OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setSslSocketFactory (sslContext.getSocketFactory()); Picasso.Builder builder = новый Picasso.Builder (это); OkHttpDownloader okHttpDownloader = новый OkHttpDownloader (okHttpClient); builder.downloader (okHttpDownloader); Picasso picasso = builder.build(); picasso.load ("https: // ..."); ' – BNK

+1

И' okHttpClient.setHostnameVerifier (getHostnameVerifier()); ' – BNK

3

В текущем состоянии развития, я хотел бы игнорировать проверку SSL, но вместо того, чтобы заменить HTTPS с HTTP

Использования Удалять, Backspace или эквивалентные операции, чтобы удалить s из схемы https в вашем URL-адресе. Готово.

Предполагается, что ваш сервер поддерживает простой HTTP. Если это не так, поговорите с тем, кто поддерживает сервер.

До сих пор опыт в обход проверки SSL (с использованием самописца)?

Самостоятельные SSL-сертификаты не используются для «обхода проверки SSL». Если вы подключаетесь к серверу HTTPS, который использует самозаверяющий сертификат, , то вы настраиваете Ion (или другие HTTP-клиенты) для распознавания этого сертификата.

Вы «обходите проверку SSL», не запрашивая URL-адрес https:// и имея сервер, который поддерживает простой URL-адрес http://.

И проблема в том, как построить управляющие службы sslContext obj/trust?

Если у вас действительно есть сервер, который использует самозаверяющий сертификат SSL, вы можете использовать my CWAC-Security library для создания TrustManager[]. Или, следуйте фрагментам Java в Nikolay Elenkov's old blog post, адаптируя их для использования с Ion.

+0

Библиотека выглядит как раз то, что мне нужно, спасибо большое – user3538235

2
1. Generate the self signed certificate by openssl libarary. 
http://stackoverflow.com/questions/10175812/how-to-create-a-self-signed-certificate-with-openssl 
2. Import the same certificate or its root certificate to your server(ISS or apache. 
3. Use following code in client 
// Load CAs from an InputStream 
// (could be from a resource or ByteArrayInputStream or ...) 
CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
// From https://www.washington.edu/itconnect/security/ca/load-der.crt 
InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt")); 
Certificate ca; 
try { 
    ca = cf.generateCertificate(caInput); 
    System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); 
} 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); 

// Tell the URLConnection to use a SocketFactory from our SSLContext 
URL url = new URL("https://certs.cac.washington.edu/CAtest/"); 
HttpsURLConnection urlConnection = 
    (HttpsURLConnection)url.openConnection(); 
urlConnection.setSSLSocketFactory(context.getSocketFactory()); 
InputStream in = urlConnection.getInputStream(); 
copyInputStreamToOutputStream(in, System.out); 

http://developer.android.com/training/articles/security-ssl.html 
+0

спасибо, проблема в copyInputStreamToOutputStream не решена? И как обратиться в библиотеку ION? – user3538235

0
try { 
      TrustManager[] wrappedTrustManagers = new TrustManager[]{ 
        new X509TrustManager() { 
         public void checkClientTrusted(X509Certificate[] chain, String authType) { 
         } 

         public void checkServerTrusted(X509Certificate[] chain, String authType) { 
         } 

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

      SSLContext sslContext = SSLContext.getInstance("TLS"); 
      sslContext.init(null, wrappedTrustManagers, null); 

      AsyncSSLSocketMiddleware sslMiddleWare = Ion.getDefault(this).getHttpClient().getSSLSocketMiddleware(); 
      sslMiddleWare.setTrustManagers(wrappedTrustManagers); 
      sslMiddleWare.setHostnameVerifier(new HostnameVerifier() { 
       public boolean verify(String hostname, SSLSession session) { 
        return true; 
       } 
      }); 
      sslMiddleWare.setSSLContext(sslContext); 

      Ion.with(this) 
        .load("https://yoururl") 
        .setBodyParameter("key1", "value1") 
        .setBodyParameter("key2", "value2") 
        .asString() 
        .setCallback(new FutureCallback<String>() { 
         @Override 
         public void onCompleted(Exception e, String result) { 
          if (result != null) 
           Log.d("responsearrived", result); 

          if (e != null) Log.d("responserror", e.toString()); 
         } 
        }); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

Это более опасно, и должны использоваться только для целей тестирования ... Но это работает, без добавления сертификатов в файловой системе Вам ... что ваш проект находится в стадии разработки, поэтому это должно вам помочь, на данный момент ...

Смежные вопросы