2011-05-10 6 views
6

POST 요청을 서버에 보내는 데 자체 HTTPS를 사용해야합니다 (자체 서명 된 인증서 사용). 이것은 내가 그것을 할 방법은 다음과 같이 정의HTTPS 및 자체 서명 된 인증서 문제

getHttpClient와
HttpClient httpClient = getHttpClient(); 

for (int i = 0; i < PARAMS.length && !mHttpPost.isAborted(); ++i) { 
    mHttpPost.setURI(URI.create(mUri + "/" + PARAMS[i].getPath())); 
    mHttpPost.setEntity(new UrlEncodedFormEntity(PARAMS[i].getContents(), HTTP.UTF_8)); 
    HttpResponse response = httpClient.execute(mHttpPost); 
    [...] 
} 

()는 다음과 같습니다

public static DefaultHttpClient getHttpClient() { 

    DefaultHttpClient client = null; 

    // Setting up parameters 
    HttpParams params = new BasicHttpParams(); 
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
    HttpProtocolParams.setContentCharset(params, "utf-8"); 
    params.setBooleanParameter("http.protocol.expect-continue", false); 

    // Setting timeout 
    HttpConnectionParams.setConnectionTimeout(params, TIMEOUT); 
    HttpConnectionParams.setSoTimeout(params, TIMEOUT); 

    // Registering schemes for both HTTP and HTTPS 
    SchemeRegistry registry = new SchemeRegistry(); 
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
    final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory(); 
    sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
    registry.register(new Scheme("https", sslSocketFactory, 443)); 

    // Creating thread safe client connection manager 
    ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry); 

    // Creating HTTP client 
    client = new DefaultHttpClient(manager, params); 

    return client; 

} 

그러나 나는 "아니 신뢰할 수있는 서버 인증서"예외를 얻을. 자기 서명 인증서에 대한 몇 가지 질문은 이미 여기에 게시되어 있지만 어느 누구도 나를 위해 일하지 않았습니다 ...

어떻게 해야할지 알고 계십니까?

몇 가지 세부 정보 : 저는 에뮬레이터에서 API 레벨 4 (Android 1.6)를 사용하고 있습니다.

답변

13

나는 마침내 그것을 해결을 수행하기 전에이 시도 :

public class CustomSSLSocketFactory extends SSLSocketFactory { 

    private SSLContext sslContext = SSLContext.getInstance("TLS"); 

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

} 

을 다음과 같이 나는 그것을 사용

public HttpClient getHttpClient() { 

    DefaultHttpClient client = null; 

    try { 

     KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     trustStore.load(null, null); 

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

     // Setting up parameters 
     HttpParams params = new BasicHttpParams(); 
     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
     HttpProtocolParams.setContentCharset(params, "utf-8"); 
     params.setBooleanParameter("http.protocol.expect-continue", false); 

     // Setting timeout 
     HttpConnectionParams.setConnectionTimeout(params, TIMEOUT); 
     HttpConnectionParams.setSoTimeout(params, TIMEOUT); 

     // Registering schemes for both HTTP and HTTPS 
     SchemeRegistry registry = new SchemeRegistry(); 
     registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
     registry.register(new Scheme("https", sf, 443)); 

     // Creating thread safe client connection manager 
     ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); 

     // Creating HTTP client 
     client = new DefaultHttpClient(ccm, params); 

     // Registering user name and password for authentication 
     client.getCredentialsProvider().setCredentials(
       new AuthScope(null, -1), 
       new UsernamePasswordCredentials(mUsername, mPassword)); 

    } catch (Exception e) { 
     client = new DefaultHttpClient(); 
    } 

    return client; 

} 

내가 찾은 다른 해결책들이 왜 나에게 효과가 없었는지 모르겠다.

+2

안녕, 나는 이것이 오래 전에 포스트 알고 작동합니다. 하지만 현재 나는이 HTTPS 연결을 고수하고있다. 보안 HTTPS 사이트를 전달하기 전에 수행해야 할 단계는 무엇입니까? –

+1

이 솔루션은 실제로 위험합니다. HTTPS를 사용하면 보안상의 이점을 버릴 수 있습니다 (코드가 맹목적으로 나쁜 인증서를 신뢰하게됩니다). – Brian

0

은의 SSLSocketFactory의 사용자 지정 하위 클래스 사용하여 요청

SSLSocketFactory ssl = (SSLSocketFactory)http.getConnectionManager().getSchemeRegistry().getScheme("https").getSocketFactory(); 
    ssl.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
+0

죄송합니다, 당신은 alreay 비슷한 방법으로 그 일을하고 있지만 그것은 나를 위해 ... – 2red13

6

은 다른 사람이 받아 들인 대답에 대한 수입을 해결하는 데 도움이됩니다 (나를 위해 효과가 있지만 자바 사이의 수입을 테스트하는 데 시간을 할애합니다. , javax. 및 org.apache.http *).

import java.io.IOException; 
import java.net.Socket; 
import java.net.UnknownHostException; 
import java.security.KeyManagementException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.UnrecoverableKeyException; 
import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 

import javax.net.ssl.SSLContext; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 

import org.apache.http.HttpVersion; 
import org.apache.http.client.HttpClient; 
import org.apache.http.conn.ClientConnectionManager; 
import org.apache.http.conn.scheme.PlainSocketFactory; 
import org.apache.http.conn.scheme.Scheme; 
import org.apache.http.conn.scheme.SchemeRegistry; 
import org.apache.http.conn.ssl.SSLSocketFactory; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 
import org.apache.http.params.BasicHttpParams; 
import org.apache.http.params.HttpConnectionParams; 
import org.apache.http.params.HttpParams; 
import org.apache.http.params.HttpProtocolParams; 
관련 문제