2012-09-21 20 views
5

Zajmuję się tworzeniem bezpiecznej usługi sieciowej pomiędzy moim samo-zaimplementowanym proxy sieciowym Java (które przekazuje żądania do rzeczywistej usługi internetowej) i aplikacją na Androida.Ponowne użycie SSL połączenia z Androidem HttpClient

W przypadku standardowego (niezabezpieczonego) połączenia http działa doskonale. Teraz chcę użyć bezpiecznego połączenia SSL między proxy a klientem Android.

To działa tak długo, jak mogę utworzyć nowy HttpClient dla każdego żądania, co jest obok marnowania zasobów bardzo wolno, ponieważ robię dwustronny uścisk dłoni dla każdego żądania.

Więc próbuję ponownie wykorzystać HttpClient dla każdego żądania, co powoduje dla bezpiecznych połączeń w następującym wyjątkiem

java.lang.IllegalStateException: Connection już otwarte. w org.apache.http.impl.conn.AbstractPoolEntry.open (AbstractPoolEntry.java:150) w org.apache.http.impl.conn.AbstractPooledConnAdapter.open (AbstractPooledConnAdapter.java:119) w org.apache. http.impl.client.DefaultRequestDirector.execute (DefaultRequestDirector.java:360) at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:555) na org.apache.http.impl.client. AbstractHttpClient.execute (AbstractHttpClient.java:487) na org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:465)

Kiedy zmienić proxy i klienta, aby bez SSL komunikacja działa bez żadnych problemów. Czy ktoś wie, co robię źle? Bardzo dziękuję za Twoją pomoc!

Przy okazji kod serwera jest całkowicie podobny, z wyjątkiem użycia SSLServerSocket z załadowanymi certyfikatami zamiast używania ServerSocket.

setup

// Set basic data 
    HttpParams params = new BasicHttpParams(); 
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
    HttpProtocolParams.setContentCharset(params, "UTF-8"); 
    HttpProtocolParams.setUseExpectContinue(params, true); 
    HttpProtocolParams.setUserAgent(params, "Android app/1.0.0"); 

    // Make pool 
    ConnPerRoute connPerRoute = new ConnPerRouteBean(12); 
    ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute); 
    ConnManagerParams.setMaxTotalConnections(params, 20); 

    // Set timeout 
    HttpConnectionParams.setStaleCheckingEnabled(params, false); 
    HttpConnectionParams.setConnectionTimeout(params, connectionTimeoutMillis); 
    HttpConnectionParams.setSoTimeout(params, socketTimeoutMillis); 
    HttpConnectionParams.setSocketBufferSize(params, 8192); 

    // Some client params 
    HttpClientParams.setRedirecting(params, false); 

stworzenie klienta HTTP parametr Client

// load truststore certificate 
      InputStream clientTruststoreIs = context.getResources().openRawResource(R.raw.server); 
      KeyStore trustStore = KeyStore.getInstance("BKS"); 
      trustStore.load(clientTruststoreIs, "server".toCharArray()); 

      // initialize trust manager factory with the read truststore 
      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
      trustManagerFactory.init(trustStore); 

      // setup client certificate 

      // load client certificate 
      InputStream keyStoreStream = context.getResources().openRawResource(R.raw.client); 
      KeyStore keyStore = KeyStore.getInstance("BKS"); 
      keyStore.load(keyStoreStream, "client".toCharArray()); 

      // initialize key manager factory with the read client 
      // certificate 
      KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
      keyManagerFactory.init(keyStore, "client".toCharArray()); 

      // initialize SSLSocketFactory to use the certificates 
      SSLSocketFactory socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, keyStore, "client", trustStore, null, null); 

      // Register http/s shemas! 
      SchemeRegistry schReg = new SchemeRegistry(); 
      schReg.register(new Scheme("https", socketFactory, port)); 
      ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg); 

      httpClient = new DefaultHttpClient(conMgr, params); 

życzenie klienta wykonanie

HttpResponse response = httpClient.execute(request); 
     HttpEntity entity = response.getEntity(); 
     in = entity.getContent(); 
     String result = convertStreamToString(in); 
     in.close(); 

Odpowiedz

0

Używasz menedżer połączeń wątku bezpieczny? Jeśli nie, może to być problem, jeśli używasz tego samego HttpClient w wielu wątkach.

Ten artykuł zawiera informacje: http://candrews.integralblue.com/2011/09/best-way-to-use-httpclient-in-android/

+0

Dzięki za odpowiedź. Tak, tak, jak widać w kodzie, który podałem. Kod działa doskonale, jeśli używam go bez SSL, nawet jeśli jest używany z różnych wątków. Ale kiedy zmienię na SSL, zrywa z wyjątkiem na górze. Jakieś inne sugestie? – user1033552

3

Mam dokładnie ten sam problem z Androidem i httpclient - to tylko wydaje się objawiać przy użyciu certyfikatu po stronie klienta, jak trzeba. Usuń autoryzację klienta i działa dobrze, nie znaleziono jeszcze rozwiązania tymczasowego.

Edit:

Włącz nieświeże sprawdzanie połączenia.

HttpConnectionParams.setStaleCheckingEnabled (parametry, prawda);

Naprawiono go dla mnie.

+0

Thx. Potwierdzam, że dzieje się tak tylko przy włączonych certyfikatach klienta i to też zostało naprawione. – icyerasor

Powiązane problemy