2011-05-10 174 views
6

我必須使用HTTPS向服務器發送POST請求(使用自簽名證書)。這就是我要做的事:定義爲HTTPS和自簽名證書問題

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); 
    [...] 
} 

隨着getHttpClient()如下:

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

我終於解開了它,使用的SSLSocketFactory的自定義子類之前:

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站點之前,我需要執行哪些步驟? – 2012-02-29 08:07:18

+1

此解決方案非常危險;您正在拋棄使用HTTPS的安全優勢(您的代碼會盲目地信任錯誤的證書)。 – Brian 2014-01-24 22:31:24

0

試試這個執行請求

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

對不起,你alreay這樣做,以類似的方式,但它爲我的作品... – 2red13 2011-05-10 08:24:52

6

用於自我記錄和幫助其他人解決導入問題接受答案(這適用於我,但花時間測試java之間的導入。 ,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;