저는 자체 구현 된 자바 웹 프록시 (실제 웹 서비스에 요청을 전달하는)와 안드로이드 애플리케이션 사이에 안전한 웹 서비스를 개발 중입니다.안드로이드 HttpClient와의 SSL 연결 재사용
표준 (안전하지 않은) HTTP 연결을 사용하면 완벽하게 작동합니다. 이제 프록시와 안드로이드 클라이언트 사이에 보안 (SSL) 연결을 사용하고 싶습니다.
각 요청에 대해 새로운 HttpClient를 인스턴스화하는 한 이것은 작동합니다. 이는 각 요청에 대해 양방향 핸드 셰이크를 수행 할 때 매우 느린 리소스 낭비 옆에 있습니다. 연결이 이미 열려 :
그래서 나는 다음과 같은 예외java.lang.IllegalStateException에서 보안 연결에 대한 결과를 각 요청에 대한 HttpClient를을 재사용하기 위해 노력하고있어. at org.apache.http.impl.conn.AbstractPoolEntry.open (AbstractPoolEntry.java:150) at org.apache.http.impl.conn.AbstractPooledConnAdapter.open (AbstractPooledConnAdapter.java:119) at org.apache. http.impl.client.DefaultRequestDirector.execute (DefaultRequestDirector.java:360) at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:555) at org.apache.http.impl.client. org.apache.http.impl.client.AbstractHttpClient.execute에서 AbstractHttpClient.execute (AbstractHttpClient.java:487) (AbstractHttpClient.java:465)
내가없는 SSL 내 프록시 클라이언트를 변경
통신은 문제없이 작동합니다. 누구도 내가 뭘 잘못하고 있는지 알아? 도와 주셔서 정말로 고맙습니다!그런데 서버 코드는 ServerSocket 대신에로드 된 인증서가있는 SSLServerSocket을 사용하는 것을 제외하면 완전히 유사합니다.
클라이언트 파라미터 설정// 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);
HTTP 클라이언트 생성
// 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);
클라이언트 요청 실행
HttpResponse response = httpClient.execute(request);
HttpEntity entity = response.getEntity();
in = entity.getContent();
String result = convertStreamToString(in);
in.close();
답변 해 주셔서 감사합니다. 네, 제가 제공 한 코드에서 알 수 있듯이 그렇게합니다. 다른 스레드에서 사용하는 경우에도 SSL없이 사용하면 코드가 완벽하게 작동합니다. 하지만 SSL로 변경하면 맨 위에 예외가 발생합니다. 다른 제안? – user1033552