2011-03-28 3 views
7

В настоящее время я пишу клиентскую часть для Android (2.2) и сервера с использованием SSL. Мне удалось обмениваться сообщениями между сервером и обычным клиентом, но Android, похоже, не слишком рад самоподписанным сертификатам. Я искал Stackoverflow и Googled. У многих и много людей возникают подобные проблемы. Все ответы, которые я нашел, пока либо не работают, либо не имеют никакого смысла. Большинство примеров кода для HTTPS, но это я не могу использовать, поскольку мне нужно общаться через сокет (SSLSocket - это мое лучшее предположение). Я пробовал много разных кодов, но сейчас я снова вернулся к нулю.SSL Client на Android

До сих пор я выяснил, что мне нужно создать сертификат (думаю, я получил это право) и пользовательский TrustManager. Очевидно, что мне не удалось найти какой-либо рабочий код, поэтому я прошу здесь, так как обычно есть некоторые действительно полезные люди.

Я ищу подробное описание того, что должно быть сделано, и некоторый код, который может быть превращен в рабочий код клиента для Android.

Заранее спасибо

ответ

1

Я сделал это с портированием родного браузера Android. Я только что изменил, как создается контекст ssl. Я обещал, что я также поставить некоторые рабочий пример на сайте SandroB но ... :)

https://market.android.com/details?id=org.sandrob

http://code.google.com/p/sandrob/source/browse/misc/examples/HttpsConnection.java

+0

Спасибо за ваш ответ. Я посмотрел на код, с которым вы связались, и выглядит интересно. Проблема в том, что он использует много классов, которые, похоже, сделаны на заказ. Я искал некоторые из них в Google и обнаружил, что они реализованы в других библиотеках. Предположим, что CertificateChainValidator, похоже, должен находиться в пакете android.net.http - но его там нет. Есть ли упрощенный рабочий пример, используя стандартные библиотеки? – Casper

1

CertificateChainValidator является частью андроид источников. По крайней мере, в версии/бирке 2.2.1_r1

Чтобы сделать его работу вы можете создать браузер от андроида источников и изменить только, как SSLContext инициализируется в HttpsConnection.java файле.

Вам нужны keyManagers (инициализированные с помощью cerfile/password) и trustManagers (доверять всем).

sslContext.engineInit (keyManagers, trustManagers, null, cache, null);

+1

Привет. Я не могу его импортировать, и, согласно http://developer.android.com/reference/android/net/http/package-summary.html, функция, похоже, не существует. Насколько я знаю, мне придется создавать таможенных менеджеров для обработки сертификатов, но я еще не нашел рабочий код. Кстати, я использую Android 2.2 (API 8). – Casper

1
public class MySSLSocketFactory extends SSLSocketFactory { 
    SSLContext sslContext = SSLContext.getInstance("TLS"); 

    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { 
     super(truststore); 

     TrustManager tm = new X509TrustManager() { 
      public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
      } 

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

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

     sslContext.init(null, new TrustManager[] { tm }, null); 
    } 

    @Override 
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { 
     return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); 
    } 

    @Override 
    public Socket createSocket() throws IOException { 
     return sslContext.getSocketFactory().createSocket(); 
    } 
} 

И HTTPClient является

public HttpClient getNewHttpClient() { 
     try { 
      KeyStore trustStore = KeyStore.getInstance(KeyStore 
        .getDefaultType()); 
      trustStore.load(null, null); 

      SSLSocketFactory sf = new MySSLSocketFactory(trustStore); 
      sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

      HttpParams params = new BasicHttpParams(); 
      HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
      HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); 

      SchemeRegistry registry = new SchemeRegistry(); 
      registry.register(new Scheme("http", PlainSocketFactory 
        .getSocketFactory(), 80)); 
      registry.register(new Scheme("https", sf, 443)); 

      ClientConnectionManager ccm = new ThreadSafeClientConnManager(
        params, registry); 

      return new DefaultHttpClient(ccm, params); 
     } catch (Exception e) { 
      return new DefaultHttpClient(); 
     } 
    } 

Надеется, что это помогает.