2013-04-02 118 views
8

雖然我訪問WSDL URL我收到例外的Android四處出現SSLHandshakeException

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 

我已經使用ksoap2庫執行WSDL文件。

我還實施了認證課程,但我得到了同樣的問題

請告訴我們,如果有這方面的任何解決方案。

我使用這兩類認證:

AndroidInsecureHttpsServiceConnectionSE類:

package com.example.androidwsdltest; 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.URL; 
import java.security.KeyManagementException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 
import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 
import java.util.Iterator; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 

import javax.net.ssl.HostnameVerifier; 
import javax.net.ssl.HttpsURLConnection; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSession; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.TrustManagerFactory; 
import javax.net.ssl.X509TrustManager; 

import org.ksoap2.HeaderProperty; 
import org.ksoap2.transport.ServiceConnection; 

import android.util.Log; 

public class AndroidInsecureHttpsServiceConnectionSE implements 
     ServiceConnection { 
    private HttpsURLConnection connection; 

    public AndroidInsecureHttpsServiceConnectionSE(String host, int port, 
      String file, int timeout) throws IOException { 
     // allowAllSSL(); 
     connection = (HttpsURLConnection) new URL("https", host, port, file) 
       .openConnection(); 
     updateConnectionParameters(timeout); 
    } 

    private static TrustManager[] trustManagers; 

    public static class EasyX509TrustManager implements X509TrustManager { 

     private X509TrustManager standardTrustManager = null; 

     /** 
     * Constructor for EasyX509TrustManager. 
     */ 
     public EasyX509TrustManager(KeyStore keystore) 
       throws NoSuchAlgorithmException, KeyStoreException { 
      super(); 
      TrustManagerFactory factory = TrustManagerFactory 
        .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
      factory.init(keystore); 
      TrustManager[] trustmanagers = factory.getTrustManagers(); 
      if (trustmanagers.length == 0) { 
       throw new NoSuchAlgorithmException("no trust manager found"); 
      } 
      this.standardTrustManager = (X509TrustManager) trustmanagers[0]; 
     } 

     /** 
     * @see 
     *  javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate 
     *  [],String authType) 
     */ 
     public void checkClientTrusted(X509Certificate[] certificates, 
       String authType) throws CertificateException { 
      standardTrustManager.checkClientTrusted(certificates, authType); 
     } 

     /** 
     * @see 
     *  javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate 
     *  [],String authType) 
     */ 
     public void checkServerTrusted(X509Certificate[] certificates, 
       String authType) throws CertificateException { 
      if ((certificates != null) && (certificates.length == 1)) { 
       certificates[0].checkValidity(); 
      } else { 
       standardTrustManager.checkServerTrusted(certificates, authType); 
      } 
     } 

     /** 
     * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() 
     */ 
     public X509Certificate[] getAcceptedIssuers() { 
      return this.standardTrustManager.getAcceptedIssuers(); 
     } 

    } 

    public static class FakeX509TrustManager implements 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 boolean isClientTrusted(X509Certificate[] chain) { 
      return true; 
     } 

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

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

    /** 
    * Allow all SSL certificates by setting up a host name verifier that passes 
    * everything and as well setting up a SocketFactory with the 
    * #FakeX509TrustManager. 
    */ 
    public static void allowAllSSL() { 

     HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { 

      @Override 
      public boolean verify(String hostname, SSLSession session) { 
       // TODO Auto-generated method stub 
       return true; 
      } 

     }); 

     SSLContext context = null; 

     if (trustManagers == null) { 
      try { 
       trustManagers = new TrustManager[] { new EasyX509TrustManager(
         null) }; 
      } catch (NoSuchAlgorithmException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (KeyStoreException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

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

    /** 
    * update the connection with the timeout parameter as well as allowing SSL 
    * if the Android version is 7 or lower (since these versions have a broken 
    * certificate manager, which throws a SSL exception saying "Not trusted 
    * security certificate" 
    * 
    * @param timeout 
    */ 
    private void updateConnectionParameters(int timeout) { 
     connection.setConnectTimeout(timeout); // 20 seconds 
     connection.setReadTimeout(timeout); // even if we connect fine we want 
              // to time out if we cant read 
              // anything.. 
     connection.setUseCaches(false); 
     connection.setDoOutput(true); 
     connection.setDoInput(true); 

     allowAllSSL(); 

     /* 
     * int buildVersion = Build.VERSION.SDK_INT; if (buildVersion <= 7) { 
     * Log.d("Detected old operating system version " + buildVersion + 
     * " with SSL certificate problems. Allowing " + "all certificates.", 
     * String.valueOf(buildVersion)); allowAllSSL(); } else { 
     * Log.d("Full SSL active on new operating system version ", 
     * String.valueOf(buildVersion)); } 
     */ 
    } 

    public void connect() throws IOException { 
     connection.connect(); 
    } 

    public void disconnect() { 
     connection.disconnect(); 
    } 

    public List getResponseProperties() { 
     Map properties = connection.getHeaderFields(); 
     Set keys = properties.keySet(); 
     List retList = new LinkedList(); 

     for (Iterator i = keys.iterator(); i.hasNext();) { 
      String key = (String) i.next(); 
      List values = (List) properties.get(key); 

      for (int j = 0; j < values.size(); j++) { 
       retList.add(new HeaderProperty(key, (String) values.get(j))); 
      } 
     } 

     return retList; 
    } 

    public void setRequestProperty(String key, String value) { 
     // We want to ignore any setting of "Connection: close" because 
     // it is buggy with Android SSL. 
     if ("Connection".equalsIgnoreCase(key) 
       && "close".equalsIgnoreCase(value)) { 
      // do nothing 
     } else { 
      connection.setRequestProperty(key, value); 
     } 
    } 

    public void setRequestMethod(String requestMethod) throws IOException { 
     connection.setRequestMethod(requestMethod); 
    } 

    public OutputStream openOutputStream() throws IOException { 
     return connection.getOutputStream(); 
    } 

    public InputStream openInputStream() throws IOException { 
     return connection.getInputStream(); 
    } 

    public InputStream getErrorStream() { 
     return connection.getErrorStream(); 
    } 

    public String getHost() { 
     return connection.getURL().getHost(); 
    } 

    public int getPort() { 
     return connection.getURL().getPort(); 
    } 

    public String getPath() { 
     return connection.getURL().getPath(); 
    } 

} 

AndroidInsecureKeepAliveHttpsTransportSE類:

package com.example.androidwsdltest; 

import java.io.IOException; 

import org.ksoap2.transport.HttpsTransportSE; 
import org.ksoap2.transport.ServiceConnection; 

public class AndroidInsecureKeepAliveHttpsTransportSE extends HttpsTransportSE { 

    private AndroidInsecureHttpsServiceConnectionSE conn = null; 
    private final String host; 
    private final int port; 
    private final String file; 
    private final int timeout; 

    public AndroidInsecureKeepAliveHttpsTransportSE(String host, int port, 
      String file, int timeout) { 
     super(host, port, file, timeout); 
     this.host = host; 
     this.port = port; 
     this.file = file; 
     this.timeout = timeout; 
    } 

    @Override 
    protected ServiceConnection getServiceConnection() throws IOException { 
     super.getServiceConnection(); 
     conn = new AndroidInsecureHttpsServiceConnectionSE(host, port, file, 
       timeout); 
     conn.setRequestProperty("Connection", "keep-alive"); 

     return conn; 
    } 
} 

使用我收到這些認證課程後SAM Ë例外

請幫助我..

在此先感謝...... :)

+0

您使用自簽名證書嗎?小心顯示代碼? – t0mm13b

+0

你是通過vpn連接嗎? –

回答

2

您有權授權的SSL證書 - 可以解決這個問題,這是解決問題的最好辦法。

如果沒有,你要努力一點點:

的概念是,使用SSL時,Android是比平時更強硬一點,你必須對你的Android證書的權利,所以對於,你應該在你的Android上有一個基本的密鑰倉庫(比如谷歌商店,但是免費,並且在你自己的Android上),並且通過一些基本的操作讓你自己的一個可信任。

  1. 在服務器上查找您的證書,並使用私鑰導出(您將擁有管理員權限)。這可以通過從開始 - >運行+ certmgr.msc運行完成。 尋找「受信任的根證書頒發機構」。找到你的證書和做外銷(密鑰工具可以裝入現有的PFX證書。對* .CER類型的證書,可能會有一點問題。
  2. 你應該有一個密鑰工具,你可以找到關於http://keytool.sourceforge.net/ 解釋可以安裝,但我更喜歡以下建議: 這是通過幫助 - 軟件更新 - 查找和安裝 - 搜索新功能.... 單擊新建遠程站點,並在名稱和URL中添加http://keytool.sourceforge.net/update,並確保其選中 命中完成。
  3. 添加一個新的密鑰庫,並加載您的證書(使用pcs12協議,選擇您可以記住的密碼)。
  4. 需要添加的代碼如下: http://developer.android.com/training/articles/security-ssl.html#UnknownCa
  5. 您應該與您的連接相關。 您可以像使用示例一樣使用HttpTransportSE :: ServiceConnection :: setSSLSocketFactory。 https://code.google.com/p/androidzon/source/browse/Androidzon/src/it/marco/ksoap2/HttpTransportSE.java?r=77 (只需創建自己的新功能,並將其連接到Web服務,如果沒有工作,去掉?WSDL)

祝你好運!

相關問題