2011-08-29 86 views
2

我在默認的httpclient中尋找忽略所有ssl錯誤(例如不可信)的可能性。我在這裏看到了很多解決方案,但是我必須導入一個特定的證書並將它添加到trustmanager,或者它用於DefaultHttpClient的HttpsUrlConnection instad。 我使用webrequests是:忽略DefaultHttpClient中的ssl錯誤

public static String makeGETRequest(String s,String encoding) 
{ 
    DefaultHttpClient http = new DefaultHttpClient(); 
    final String username = "USERNAME"; 
    final String password = "PASSWORD"; 
    UsernamePasswordCredentials c = new UsernamePasswordCredentials(username,password); 
    BasicCredentialsProvider cP = new BasicCredentialsProvider(); 
    cP.setCredentials(AuthScope.ANY, c); 
    http.setCredentialsProvider(cP); 
    HttpResponse res; 
    try { 

     res = http.execute(new HttpGet(s)); 
     InputStream is = res.getEntity().getContent(); 
     BufferedInputStream bis = new BufferedInputStream(is); 
     ByteArrayBuffer baf = new ByteArrayBuffer(50); 
     int current = 0; 
     while((current = bis.read()) != -1){ 
       baf.append((byte)current); 
     } 

     return new String(baf.toByteArray(),encoding); 
     } 
    catch (ClientProtocolException e) { 
     // TODO Auto-generated catch block 
     return "error: " + e.getMessage(); 
    } 
    catch (IOException e) { 
     // TODO Auto-generated catch block 
     return "error: " + e.getMessage(); 
    } 

} 

和:

public static String makePOSTRequest(String s, List <NameValuePair> nvps,String encoding) 
{ 
    DefaultHttpClient http = new DefaultHttpClient(); 
    final String username = "USERNAME"; 
    final String password = "PASSWORD"; 
    UsernamePasswordCredentials c = new UsernamePasswordCredentials(username,password); 
    BasicCredentialsProvider cP = new BasicCredentialsProvider(); 
    cP.setCredentials(AuthScope.ANY, c); 
    http.setCredentialsProvider(cP); 
    HttpResponse res; 
    try { 
     HttpPost httpost = new HttpPost(s); 
     httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.DEFAULT_CONTENT_CHARSET)); 
     res = http.execute(httpost); 
     InputStream is = res.getEntity().getContent(); 
     BufferedInputStream bis = new BufferedInputStream(is); 
     ByteArrayBuffer baf = new ByteArrayBuffer(50); 
     int current = 0; 
     while((current = bis.read()) != -1){ 
       baf.append((byte)current); 
     } 
     res = null; 
     httpost = null; 
     String ret = new String(baf.toByteArray(),encoding); 
     return ret; 
     } 
    catch (ClientProtocolException e) { 
     // TODO Auto-generated catch block 
     return e.getMessage(); 
    } 
    catch (IOException e) { 
     // TODO Auto-generated catch block 
     return e.getMessage(); 
    } 

} 

沒有人知道如何忽略這個代碼SSL錯誤?

編輯: 因爲我相信只有一個特定的(已過期)證書,我嘗試覆蓋DefaultHttpClient以下列方式:

public class MyHttpClient extends DefaultHttpClient { 
final Context context; 

    public MyHttpClient(Context context) { 
    this.context = context; 
    } 

    @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.mykeystore); 
     try { 
     trusted.load(in, "mypassword".toCharArray()); 
     } finally { 
     in.close(); 
     } 
     return new SSLSocketFactory(trusted); 
    } catch (Exception e) { 
     throw new AssertionError(e); 
    } 
    } 

}

在R.raw文件。 mykeystore是一個.bks文件,我使用Portecle創建,我創建了一個新的bks並導入了已過期證書的存儲區域,它看起來可以正常工作,而且密鑰存儲沒有錯誤,但是如果我執行請求, IO異常與消息「沒有對等證書」,可能是什麼問題?

+1

「忽略SSL錯誤(例如不信任)」是不安全的。請參閱RFC 2246.如果您不希望它安全,爲什麼要使用SSL? – EJP

+0

感謝轉化爲評論;)正如我寫的,過期的SSL證書來自第三方代理,我告訴他們安裝一個有效的代理,但我必須wirite快速解決方法,以使我的客戶的功能,而證書已過期... – 2red13

+0

按照EJP的評論,有選擇性地容忍過期證書並讓絕對通過任何證書是非常不同的事情。 – Bruno

回答

11

我解決了這個問題。它的工作原理,如果你使用上面的要求,但不是在DefaultHttpClient,用你自己的版本:

public class MyHttpClient extends DefaultHttpClient { 
final Context context; 
TrustManager easyTrustManager = new X509TrustManager() { 
    @Override 
    public void checkClientTrusted(
      X509Certificate[] chain, 
      String authType) throws CertificateException { 
    } 

    @Override 
    public void checkServerTrusted(
      X509Certificate[] chain, 
      String authType) throws CertificateException { 
    } 

    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
     return null; 
    }  
}; 
    public MyHttpClient(Context context) { 
    this.context = context; 
    } 

    @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 MySSLSocketFactory newSslSocketFactory() { 
    try { 
     KeyStore trusted = KeyStore.getInstance("BKS");  
     try { 
     trusted.load(null, null); 

     } finally { 
     } 

     MySSLSocketFactory sslfactory = new MySSLSocketFactory(trusted); 
     sslfactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
     return sslfactory; 
    } catch (Exception e) { 
     throw new AssertionError(e); 
    } 

    } 
    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(); 
     } 
    } 
    } 
+0

這段代碼會導致操作系統版本2.2中的破損管道錯誤,在2.3.3中修復+ – 2red13

+0

未使用的字段easyTrustManager! –

+0

此代碼適用於我。謝謝 –