Как использовать самоподписанный 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 и получил 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 должны правильно строить, как это исправить?

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

Solutions Collecting From Web of "Как использовать самоподписанный SSL в сетевой библиотеке Android (ION)?"

Для вашей проблемы, IMO, вы можете обратиться к моему следующему образцу кода. Я тестировал свой веб-сервис (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"} 

Поскольку текущим статусом является развитие, я хотел бы игнорировать проверку SSL, но вместо замены https с помощью http

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

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

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

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

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

И проблема в том, как построить sslContext obj / trust manager?

Если у вас есть сервер, который использует самоподписанный SSL-сертификат, вы можете использовать мою библиотеку CWAC-Security для создания TrustManager[] . Или следуйте фрагментам Java в старом блоге Николая Еленкова , адаптируя их для использования с Ion.

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

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