2015-04-21 56 views
1

我正在運行使用HTTPS的網站,並使用來自Comodo的SSL證書。 Qualys爲該網站提供了A +分數,並且同一個網址在Android版Chrome中無誤地運行。當我嘗試使用loopj連接到Android應用程序的網站時,出現SSLPeerUnverifiedException異常。我必須手動提供證書信息嗎?如何在Android上的loopj中支持Comodo SSL證書?

我看到此行爲與默認AsyncHttpClient例如:

AsyncHttpClient client = new AsyncHttpClient(); 
client.get("https://myapp.com", new AsyncHttpResponseHandler() { 

    @Override 
    public void onStart() { 
     // called before request is started 
    } 

    @Override 
    public void onSuccess(int statusCode, Header[] headers, byte[] response) { 
     // called when response HTTP status is "200 OK" 
    } 

    @Override 
    public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { 
     // called when response HTTP status is "4XX" (eg. 401, 403, 404) 
    } 

    @Override 
    public void onRetry(int retryNo) { 
     // called when request is retried 
    } 
}); 

例外:

04-20 21:59:57.092: W/System.err(8824): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate 
04-20 21:59:57.102: W/System.err(8824):  at com.android.org.conscrypt.SSLNullSession.getPeerCertificates(SSLNullSession.java:104) 
04-20 21:59:57.102: W/System.err(8824):  at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93) 
04-20 21:59:57.102: W/System.err(8824):  at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:388) 
04-20 21:59:57.102: W/System.err(8824):  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:214) 
04-20 21:59:57.102: W/System.err(8824):  at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:167) 
04-20 21:59:57.102: W/System.err(8824):  at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:125) 
04-20 21:59:57.102: W/System.err(8824):  at org.apache.http.impl.client.DefaultRequestDirector.executeSB(DefaultRequestDirector.java:831) 
04-20 21:59:57.102: W/System.err(8824):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:697) 
04-20 21:59:57.102: W/System.err(8824):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:575) 
04-20 21:59:57.102: W/System.err(8824):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:491) 
04-20 21:59:57.102: W/System.err(8824):  at com.loopj.android.http.AsyncHttpRequest.makeRequest(AsyncHttpRequest.java:147) 
04-20 21:59:57.102: W/System.err(8824):  at com.loopj.android.http.AsyncHttpRequest.makeRequestWithRetries(AsyncHttpRequest.java:178) 
04-20 21:59:57.102: W/System.err(8824):  at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:109) 
04-20 21:59:57.102: W/System.err(8824):  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
04-20 21:59:57.102: W/System.err(8824):  at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
04-20 21:59:57.102: W/System.err(8824):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
04-20 21:59:57.102: W/System.err(8824):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
04-20 21:59:57.102: W/System.err(8824):  at java.lang.Thread.run(Thread.java:818) 

回答

1

作爲替代循環J,你可以創建一個將在執行 任務的的AsyncTask程序。幾乎和循環一樣。我使用下面的類來執行HTTP/S請求,並完成這項工作。

class GetHTTPSTask extends AsyncTask<Void, Void, Boolean> 
    { 
    private String mUrl; 

    public GetHTTPSTask(String url) 
    { 
     this.mUrl = url; 
    } 

    @Override 
    protected Boolean doInBackground(Void... params) 
    { 
     try 
     { 
     URL urlConnection = new URL(mUrl); 
     HttpURLConnection connection = (HttpURLConnection) urlConnection 
      .openConnection(); 
     connection.setDoInput(true); 
     connection.connect(); 
     InputStream input = connection.getInputStream(); 

     return Boolean.TRUE; 
     } 
     catch (Exception e) 
     { 
     e.printStackTrace(); 
     } 
     return null; 
    } 
    @Override 
    protected void onPostExecute(Boolean result) 
    { 
     if (result != null) 
     { 
     // Connection was successful 
     // Do something here 
     } 
     super.onPostExecute(result); 
    } 
    } 

,並使用它:

new GetHTTPSTask("https://www.google.com/").execute(); 
0

原來服務器不能依靠SNI如果你使用Apache庫。

如果你有服務器的控制權,你可以配置它有一個唯一的IP。或者,修復在客戶端上:

Android docs

幸運的是,HttpsURLConnection的支持SNI由於Android 2.3。 不幸的是,Apache HTTP Client不支持,這是我們不鼓勵使用它的許多原因之一。如果您需要支持 Android 2.2(或更早版本)或Apache HTTP Client,則需要採取一種解決方法,即在唯一端口上設置 替代虛擬主機,以便明確返回哪個服務器證書 。