Intereting Posts
Как определить, отображается ли раскрывающееся меню выше или ниже счетчика в андроиде? Как опубликовать сообщение на стене друзей facebook в Android Как немедленно заменить текущий тост на второй, не дожидаясь окончания текущего? Как реализовать рекламные объявления для родных в Listview с помощью CursorAdapter AudioManager отправляет сообщение обработчику по мертвой теме? Проблема в обработчике с сообщениями в android Могу ли я тестировать уведомления о статусных базах с помощью платформы тестирования Android? Иерархия активности типа несовместима при расширении ActionBarActivity Android – onAttach (Контекст), не вызываемый API 23 Sprite Rotation в Android с помощью Canvas.DrawBitmap. Я близка, что я делаю неправильно? Как отключить заполнение на TextInputLayout? Wear App и с настраиваемым типом сборки с applicationIdSuffix Принуждение adjustPan в активности, содержащей ScrollView StartActivityForResult и Intents Дополнительно, кажется, что дополнительные функции не отбрасываются Как перемещать camra на определенный маркер в google maps v2 в android

Андроид HTTP HTTP-запрос с использованием самозаверяющего сертификата и CA

У меня есть приложение для Android, которое подключается к веб-сервису SSL, который мы размещаем. Веб-сервер является apache и имеет собственный CA, который мы создали, и самоподписанный сертификат SSL.

Я импортировал наш сертификат ЦС на планшет Android в разделе «Сертификаты доверенных пользователей» в разделе «Безопасность».

Я проверил доступ к веб-серверу и могу подтвердить, что сертификат веб-службы отображается как действительный (снимок экрана ниже)

Действительный сертификат

Вот сертификат в настройках безопасности:

Доверенный сертификат

Теперь, когда я пытаюсь получить доступ к веб-сервису в своем приложении, я запускаю исключение «Нет равного сертификата».

Это упрощенная реализация SSL:

public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // allows network on main thread (temp hack) StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); SchemeRegistry schemeRegistry = new SchemeRegistry(); //schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); schemeRegistry.register(new Scheme("https", newSSLSocketFactory(), 443)); HttpParams params = new BasicHttpParams(); SingleClientConnManager mgr = new SingleClientConnManager(params, schemeRegistry); HttpClient client = new DefaultHttpClient(mgr, params); HttpPost httpRequest = new HttpPost("https://our-web-service.com"); try { client.execute(httpRequest); } catch (Exception e) { e.printStackTrace(); // } } /* * Standard SSL CA Store Setup // */ private SSLSocketFactory newSSLSocketFactory() { KeyStore trusted; try { trusted = KeyStore.getInstance("AndroidCAStore"); trusted.load(null, null); Enumeration<String> aliases = trusted.aliases(); while (aliases.hasMoreElements()) { String alias = aliases.nextElement(); X509Certificate cert = (X509Certificate) trusted.getCertificate(alias); Log.d("", "Alias="+alias); Log.d("", "Subject DN: " + cert.getSubjectDN().getName()); Log.d("", "Issuer DN: " + cert.getIssuerDN().getName()); } SSLSocketFactory sf = new SSLSocketFactory(trusted); sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); return sf; } catch (Exception e) { // TODO Auto-generated catch block throw new AssertionError(e); } } } 

Цикл while просто выплевывает сертификаты, и я вижу свой собственный ЦС в журналах. Но я по-прежнему получаю исключение «No Peer Certificate».

10-17 18: 29: 01.234: I / System.out (4006): Отсутствует одноранговый сертификат

Нужно ли вручную загружать мой сертификат CA в эту реализацию?

Solutions Collecting From Web of "Андроид HTTP HTTP-запрос с использованием самозаверяющего сертификата и CA"

Решено с помощью: HttpsURLConnection

 URLConnection conn = null; URL url = new URL(strURL); conn = url.openConnection(); HttpsURLConnection httpsConn = (HttpsURLConnection) conn; 

Это, похоже, отлично работает с установленными CA сертификатами.

Вы также можете выполнить задачу, используя DefaultHttpClient , хотя здесь предлагается :

Предпочитаете HttpURLConnection для нового кода

Обратите внимание также на импорт или добавление сертификата в приложение, поскольку у вас могут возникнуть проблемы с обновлением сертификата, когда он истечет.

Здесь, как получить DefaultHttpClient доверяющий самозаверяющему сертификату:

  * This method returns the appropriate HttpClient. * @param isTLS Whether Transport Layer Security is required. * @param trustStoreInputStream The InputStream generated from the BKS keystore. * @param trustStorePsw The password related to the keystore. * @return The DefaultHttpClient object used to invoke execute(request) method. private DefaultHttpClient getHttpClient(boolean isTLS, InputStream trustStoreInputStream, String trustStorePsw) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException, UnrecoverableKeyException { DefaultHttpClient client = null; SchemeRegistry schemeRegistry = new SchemeRegistry(); Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 8080); schemeRegistry.register(http); if(isTLS) { KeyStore trustKeyStore = null; char[] trustStorePswCharArray = null; if(trustStorePsw!=null) { trustStorePswCharArray = trustStorePsw.toCharArray(); } trustKeyStore = KeyStore.getInstance("BKS"); trustKeyStore.load(trustStoreInputStream, trustStorePswCharArray); SSLSocketFactory sslSocketFactory = null; sslSocketFactory = new SSLSocketFactory(trustKeyStore); Scheme https = new Scheme("https", sslSocketFactory, 8443); schemeRegistry.register(https); } HttpParams httpParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParams, CONNECTION_TIMEOUT); HttpConnectionParams.setSoTimeout(httpParams, SOCKET_TIMEOUT); ClientConnectionManager clientConnectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry); client = new DefaultHttpClient(clientConnectionManager, httpParams); return client; } 

И здесь, как получить HttpsURLConnection :

  * This method set the certificate for the HttpsURLConnection * @param url The url to contact. * @param certificateInputStream The InputStream generated from the .crt certificate. * @param certAlias The alias for the certificate. * @return The returned HttpsURLConnection private HttpsURLConnection getHttpsURLConnection(URL url, InputStream certificateInputStream, String certAlias) throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException { HttpsURLConnection connection = null; CertificateFactory certFactory = null; Certificate cert = null; KeyStore keyStore = null; TrustManagerFactory tmFactory = null; SSLContext sslContext = null; // Load certificates from an InputStream certFactory = CertificateFactory.getInstance("X.509"); cert = certFactory.generateCertificate(certificateInputStream); certificateInputStream.close(); // Create a KeyStore containing the trusted certificates keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry(certAlias, cert); // Create a TrustManager that trusts the certificates in our KeyStore tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmFactory.init(keyStore); // Create an SSLContext that uses our TrustManager sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmFactory.getTrustManagers(), null); connection = (HttpsURLConnection)url.openConnection(); connection.setSSLSocketFactory(sslContext.getSocketFactory()); return connection; }