2011-11-22 26 views
1

我一直在試圖爲年齡來得到這個工作 - 但無論我做什麼,我的HTTP * 小號 * POST總會讓步 HttpUtils: javax.net.ssl.SSLException: Not trusted server certificateAndroid的HTTPS郵政 - 不工作

我基本上遵循了這一tutorial

  • 我成功從 服務器獲取公共證書(mycert.pem)。
  • 我使用Bouncy Castle成功創建了證書的密鑰庫
  • 我在實現自定義Apache HttpClient時失敗了。這裏是我的 代碼:

    import android.content.Context; 
    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.SingleClientConnManager; 
    import org.apache.http.params.HttpParams; 
    import java.io.InputStream; 
    import java.security.KeyStore; 
    
    public class MyHttpClient extends DefaultHttpClient { 
        final Context context; 
    
        public MyHttpClient(Context context) { 
        this.context = context; 
        } 
    
        public MyHttpClient(Context context2, HttpParams myParams) { 
         super(myParams); 
         this.context= context2; 
    } 
    
    @Override protected ClientConnectionManager createClientConnectionManager() { 
        SchemeRegistry registry = new SchemeRegistry(); 
        registry.register(
         new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
        registry.register(new Scheme("https", newSslSocketFactory(), 443)); 
        return new SingleClientConnManager(getParams(), registry); 
        } 
    
        private SSLSocketFactory newSslSocketFactory() { 
        try { 
         KeyStore trusted = KeyStore.getInstance("BKS"); 
         InputStream in = context.getResources().openRawResource(R.raw.mystore); 
         try { 
         trusted.load(in, "password".toCharArray()); 
         } finally { 
         in.close(); 
         } 
         return new SSLSocketFactory(trusted); 
        } catch (Exception e) { 
         throw new AssertionError(e); 
        } 
        } 
    } 
    

    在我的HTTP請求的類,構建POST:

    public class HttpRequest { 
    MyHttpClient httpClient; 
    HttpContext localContext; 
    private String ret; 
    
    HttpResponse response = null; 
    HttpPost httpPost = null; 
    HttpGet httpGet = null; 
    
    public HttpRequest(Context context){ 
        HttpParams myParams = new BasicHttpParams(); 
    
        HttpConnectionParams.setConnectionTimeout(myParams, 10000); 
        HttpConnectionParams.setSoTimeout(myParams, 10000); 
        httpClient = new MyHttpClient(context, myParams);  
        localContext = new BasicHttpContext();  
    } 
    
    public String sendPost(String url, String data, String contentType) { 
        ret = null; 
    
        httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109); 
    
        httpPost = new HttpPost(url); 
        response = null; 
    
        StringEntity tmp = null;   
    
        httpPost.setHeader("User-Agent", "SET YOUR USER AGENT STRING HERE"); 
        httpPost.setHeader("Accept", "text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); 
    
        if (contentType != null) { 
         httpPost.setHeader("Content-Type", contentType); 
        } else { 
         httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
        } 
    
        try { 
         tmp = new StringEntity(data,"UTF-8"); 
        } catch (UnsupportedEncodingException e) { 
         Log.e("Log", "HttpUtils : UnsupportedEncodingException : "+e); 
        } 
    
        httpPost.setEntity(tmp); 
    
        try { 
         response = httpClient.execute(httpPost,localContext); 
    
         if (response != null) { 
          ret = EntityUtils.toString(response.getEntity()); 
         } 
        } catch (Exception e) { 
         Log.e("Log", "HttpUtils: " + e); 
        } 
    
        return ret; 
    } 
    } 
    

我的崗位工作正常,非HTTPS網站。任何幫助將不勝感激。

回答

1

查看錯誤信息:

HttpUtils:javax.net.ssl.SSLException:不受信任的服務器證書

這意味着正是它說 - 服務器沒有使用可信證書。我敢打賭,如果您嘗試使用Firefox或IE訪問相同的服務器,您會得到類似的錯誤。

+0

Android廠商(在網頁視圖或在原來的問題等),相信很少證書(也許一半常見的?),當瀏覽器不運行有將不會彈出問題,要求最終用戶接受不可信的證書。因此,您必須在您自己的代碼中解決這個問題,如以下兩個示例中所示。 – user288299

0

使用此類來獲得您的HttpClient.And檢查是否有幫助。

package com.android.MyCellFamily.DAHttp;

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.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.HttpParams; 
import org.apache.http.params.HttpProtocolParams; 
import org.apache.http.protocol.HTTP; 

public class MySSLSocketFactory extends SSLSocketFactory { 
    SSLContext sslContext = SSLContext.getInstance("TLS"); 

    public MySSLSocketFactory(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 static DefaultHttpClient getNewHttpClient() { 
    try { 
     KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     trustStore.load(null, null); 

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

     HttpParams params = new BasicHttpParams(); 
     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
     HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); 

     SchemeRegistry registry = new SchemeRegistry(); 
     registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
     registry.register(new Scheme("https", sf, 443)); 

     ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); 

     return new DefaultHttpClient(ccm, params); 
    } catch (Exception e) { 
     return new DefaultHttpClient(); 
    } 
} 
} 
1

有時https網址在android webview中顯示空白屏幕。這是因爲你必須信任ssl認證,或者你需要覆蓋webview客戶端的ssl錯誤。

以下webview客戶端提供訪問https url所需的功能。 這裏shouldOverrideUrlLoading用於允許在webview中重定向url,onReceivedSslError這oneiIgnore SSL證書錯誤來訪問https url。


Webviewclient:

private class MyWebViewClient extends WebViewClient 
      { 
     @Override 
     public void onPageStarted(WebView view, String url, Bitmap favicon) { 
      System.out.println("onPageStarted: " + url); 
     } 

     @Override 
     public boolean shouldOverrideUrlLoading(WebView webView, String url) { 
      System.out.println("shouldOverrideUrlLoading: " + url); 
      webView.loadUrl(url); 
      return true; 
     } 

     @Override 
     public void onPageFinished(WebView webView, String url) { 
      System.out.println("onPageFinished: " + url);    

     } 

     @Override 
     public void onReceivedSslError(WebView view, SslErrorHandler handler, 
       SslError error) { 
      handler.proceed(); // Ignore SSL certificate errors 
     } 

    } 
+0

上面的例子中只剩下OnReceivedSslError(...)方法,它傳遞了cookies並且都很好。這節省了我的一天,非常感謝! – user288299