2013-04-02 12 views
8

Chociaż mam dostępu url WSDL otrzymuję wyjątek w AndroidPierwsze SSLHandShakeException

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

Użyłem ksoap2 bibliotekę uruchomieniu pliku WSDL.

ja również realizowane zajęcia certyfikacyjne, ale otrzymuję ten sam problem

proszę powiedzieć, czy istnieje rozwiązanie tego problemu.

używam tych dwóch klas do certyfikacji: Klasa

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 klasa:

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; 
    } 
} 

Po użyciu tych klas certyfikacyjne otrzymuję sam e wyjątek

Proszę mi pomóc ..

góry dzięki ...... :)

+0

Czy używasz certyfikatów z podpisem własnym? Chcesz pokazać kod? – t0mm13b

+0

Czy łączysz się przez VPN? –

Odpowiedz

2

Będziesz mieć autoryzowany certyfikat SSL - który może rozwiązać ten problem, i że jest najlepszym sposobem rozwiązania problemu.

Jeśli nie, trzeba pracować trochę:

Koncepcja jest, że przy użyciu protokołu SSL, Android jest trochę twardszy niż zwykle, a będziecie mieć prawa certyfikatów na Android, więc za to Będziesz mieć podstawowy magazyn kluczy na swoim Androidzie (np. sklep Google, ale za darmo i na własnym Androidzie) i sprawić, że twój własny będzie zaufany, przez kilka podstawowych manipulacji.

  1. Znajdź swój certyfikat na serwerze i wyeksportuj kluczem prywatnym (będziesz mieć uprawnienia administratora). Można to zrobić, uruchamiając program start-> run + certmgr.msc. Wyszukaj "Zaufane główne urzędy certyfikacji". Odszukaj swój certyfikat i wyeksportuj (keytool może załadować istniejący certyfikat pfx na * .cer rodzaj certyfikatu, może być niewielki problem
  2. Będziesz miał keytool. Możesz znaleźć wyjaśnienie na http://keytool.sourceforge.net/ Możesz zainstalować, ale Wolę następujące zalecenie: Można to zrobić za pomocą Pomocy - Aktualizacje oprogramowania - Znajdź i zainstaluj - Wyszukaj nową funkcję ... Kliknij opcję Nowa witryna zdalna, a następnie dodaj nazwę i URL do nazwy http://keytool.sourceforge.net/update, a następnie sprawdź, czy jest zaznaczona. .
  3. Dodaj nowy magazyn kluczy i załaduj certyfikat (użyj protokołu pcs12, wybierz hasło, które możesz zapamiętać).
  4. Kod należy dodać to: http://developer.android.com/training/articles/security-ssl.html#UnknownCa
  5. Powiążesz swoje połączenie. Używasz HttpTransportSE :: ServiceConnection :: setSSLSocketFactory jak przykład. https://code.google.com/p/androidzon/source/browse/Androidzon/src/it/marco/ksoap2/HttpTransportSE.java?r=77 (Wystarczy utworzyć nową funkcję własną rękę, i podłączyć go do serwisu WWW. Jeśli nie działa, usunąć? WSDL)

Powodzenia !!!