2010-08-09 54 views
12

我使用KSOAP2來管理Android中的SOAP,但它使用https作爲SOAP URL,並且出現此錯誤:javax.net.ssl.SSLException:不可信服務器證書
由於正常錯誤,該證書不受信任,但任何人都知道如何解決此錯誤? 我無法管理證書,因爲來自其他公司,我無權更改它。KSOAP 2 Android與HTTPS

感謝

回答

10

我還不能評論,所以我發表我的意見,rallat答案在這裏。他的解決方案有效,但需要進一步解釋。使用SSL運行ksoap2:

  1. ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar在項目
  2. 下載ksoap2來源從https://github.com/mosabua/ksoap2-android/tree/(ksoap2庫)複製HttpTransportSE.javaServiceConnectionSE.java(我還需要複製Transport.javaServiceConnection.javaHeaderProperty.java
  3. 。刪除這些文件的進口,並確保他們所使用的文件(而不是從ksoap2.jar進口)
  4. 使用rallat答案(我複製粘貼吧):

    • ServiceConnectionSE.java添加此爲接受不受信任的證書:

      private TrustManager[] trustAllCerts = new TrustManager[] { 
          new X509TrustManager() { 
           public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
            return null; 
           } 
           public void checkClientTrusted(
            java.security.cert.X509Certificate[] certs, String authType) { 
           } 
           public void checkServerTrusted(
            java.security.cert.X509Certificate[] certs, String authType) { 
           } 
          } 
      }; 
      
    • 然後使用此構造函數來 允許不受信任的證書,而不是 驗證主機名:

      public ServiceConnectionSE(String url) throws IOException { 
          try { 
           SSLContext sc = SSLContext.getInstance("TLS"); 
           sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
           HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
          } catch (Exception e) { 
           e.getMessage(); 
          } 
          connection = (HttpsURLConnection) new URL(url).openConnection(); 
          ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier()); 
      }  
      
    • 其次構造器

      public ServiceConnectionSE(Proxy proxy, String url) throws IOException { 
          try { 
           SSLContext sc = SSLContext.getInstance("TLS"); 
           sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
           HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
          } catch (Exception e) { 
           e.getMessage(); 
          } 
          connection = (HttpsURLConnection) new URL(url).openConnection(); 
          ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier()); 
      
          connection.setUseCaches(false); 
          connection.setDoOutput(true); 
          connection.setDoInput(true); 
      } 
      
  5. 在你的代碼,只需使用:

    HttpTransportSE aht = new HttpTransportSE(URL);  
    aht.call(SOAP_ACTION, envelope); 
    

其他事情在教程

+1

@Zirael ...感謝您的幫助...它渴望知道而不是解決辦法,如果有安全證書...我如何繼續進一步... ..? – 2013-03-13 10:23:50

+0

使用提供的鏈接無法找到ksoap的來源 - 已損壞。 = \ 更新:我發現它...只是使用:https://github.com/mosabua/ksoap2-android/ – micyunu 2014-04-30 16:38:18

4

我找到自己的答案

  • 上ServiceConnectionSE.java添加此爲接受不受信任的證書:

    private TrustManager[] trustAllCerts = new TrustManager[]{ 
        new X509TrustManager() { 
         public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
          return null; 
         } 
         public void checkClientTrusted(
          java.security.cert.X509Certificate[] certs, String authType) { 
         } 
         public void checkServerTrusted(
          java.security.cert.X509Certificate[] certs, String authType) { 
         } 
        } 
    }; 
    
  • 然後在構造函數中添加此允許不可信證書和未驗證的主機名:

    try { 
         SSLContext sc = SSLContext.getInstance("TLS"); 
         sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
         HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
        } catch (Exception e) { 
         e.getMessage(); 
        } 
        connection = (HttpsURLConnection) new URL(url).openConnection(); 
        ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier()); 
    
3

創建一個新類FakeX509TrustManager辦理證書有問題,

FakeX509TrustManager.allowAllSSL(); 
    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); 

新創建的類是如下:

public class FakeX509TrustManager implements X509TrustManager { 

    private static TrustManager[] trustManagers; 
    private static final X509Certificate[] _AcceptedIssuers = new 
X509Certificate[] {}; 

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

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

    public boolean isClientTrusted(X509Certificate[] chain) { 
      return true; 
    } 

    public boolean isServerTrusted(X509Certificate[] chain) { 
      return true; 
    } 

    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
      return _AcceptedIssuers; 
    } 

    public static void allowAllSSL() { 
      HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() 
{ 
        @Override 
        public boolean verify(String hostname, SSLSession session) { 
          return true; 
        } 

      }); 

      SSLContext context = null; 
      if (trustManagers == null) { 
        trustManagers = new TrustManager[] { new FakeX509TrustManager() }; 
      } 

      try { 
        context = SSLContext.getInstance("TLS"); 
        context.init(null, trustManagers, new SecureRandom()); 
      } catch (NoSuchAlgorithmException e) { 
        e.printStackTrace(); 
      } catch (KeyManagementException e) { 
        e.printStackTrace(); 
      } 

     HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); 
    } 

} 
+0

嚴重的+1 jowett ...我把你的代碼放在我的活動結束時,我所有的要做的是讓FakeX509TrustManager靜態化,並且通過了......我已經閱讀了超過幾個SO帖子,這是迄今爲止最容易實現的。注意這篇文章中以前答案的日期......足夠說了。你有沒有任何資源最簡單的方法不信任所有的生產代碼證書? – whyoz 2013-08-09 23:48:32

+0

@whyoz抱歉,沒有資源。 – jowett 2014-09-01 07:57:25

11

再次檢查這個問題,我發現我的一個更乾淨的解決方案。不需要修改KSOAP2文件。

在您的項目中,鏈接ksoap2-android-assembly-3.0.0-jar,不作任何修改。

接下來,創建一個與此代碼名爲SSLConnection.java文件:

package com.example.mypackage; 

import android.util.Log; 

import javax.net.ssl.HostnameVerifier; 
import javax.net.ssl.SSLSession; 
import javax.net.ssl.TrustManager; 
import java.security.KeyManagementException; 
import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 
import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 

public class SSLConection { 

    private static TrustManager[] trustManagers; 

    public static class _FakeX509TrustManager implements javax.net.ssl.X509TrustManager { 
     private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{}; 

     public void checkClientTrusted(X509Certificate[] arg0, String arg1) 
       throws CertificateException { 
     } 

     public void checkServerTrusted(X509Certificate[] arg0, String arg1) 
       throws CertificateException { 
     } 

     public X509Certificate[] getAcceptedIssuers() { 
      return (_AcceptedIssuers); 
     } 
    } 

    public static void allowAllSSL() { 

     javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { 
      @Override 
      public boolean verify(String hostname, SSLSession session) { 
       return true; 
      } 
     }); 

     javax.net.ssl.SSLContext context; 

     if (trustManagers == null) { 
      trustManagers = new TrustManager[]{new _FakeX509TrustManager()}; 
     } 

     try { 
      context = javax.net.ssl.SSLContext.getInstance("TLS"); 
      context.init(null, trustManagers, new SecureRandom()); 
      javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); 
     } catch (NoSuchAlgorithmException e) { 
      Log.e("allowAllSSL", e.toString()); 
     } catch (KeyManagementException e) { 
      Log.e("allowAllSSL", e.toString()); 
     } 
    } 
} 

,並呼籲通過KSOAP2服務器方法之前剛剛打電話SSLConection.allowAllSSL();。這一切,爲我工作。所有SSL證書都被接受,我可以使用帶有https協議的KSOAP2。

+0

感謝您添加您的代碼 – rallat 2013-09-23 17:23:38

+0

完美的簡單解決方案!謝謝:) – OmarBizreh 2014-01-31 09:24:11

+0

很高興幫助! :-) – Neonigma 2014-02-11 12:41:14