2010-08-09 5 views
12

Я использую KSOAP2 для управления SOAP в Android, но он использует https для URL-адреса SOAP, и я получаю эту ошибку: javax.net.ssl.SSLException: сертификат несертифицированного сервера
Обычная ошибка, потому что сертификат не доверен, но кто знает, как обходиться с этой ошибкой? Я не могу управлять сертификатом, потому что он из другой компании, и у меня нет доступа к его изменению.KSOAP 2 Android с HTTPS

Благодаря

ответ

10

Я еще не могу прокомментировать, поэтому отправлю свои комментарии на rallat здесь. Его решение работает, но ему нужны дополнительные объяснения. Чтобы запустить ksoap2 с SSL:

  1. Помещенный ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar в проекте
  2. источники Скачать ksoap2 из https://github.com/mosabua/ksoap2-android/tree/ (хранилище ksoap2)
  3. Копия HttpTransportSE.java, ServiceConnectionSE.java (я тоже нужно скопировать Transport.java, ServiceConnection.java и HeaderProperty.java).Удалить импорт из этих файлов и убедитесь, что они используют свои файлы (не импортирует из 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 ... Спасибо за помощь, это помогло ... Я очень хотел узнать, а не работать, если бы был сертификат безопасности ... Как мне продолжить дальше ...? –

+0

Невозможно найти источники ksoap, используя предоставленную ссылку - ее сломан. = \ обновление: я нашел его ... просто использую: https: //github.com/mosabua/ksoap2-android/ – micyunu

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

Serious +1 jowett ... Я положил ваш код в конце своей деятельности, и все, что у меня было чтобы сделать FakeX509TrustManager статичным, и он прошел прямо ... Я прочитал более чем несколько сообщений SO, и это было проще всего реализовать. Обратите внимание на даты предыдущих ответов в этом сообщении ... достаточно сказано. У вас есть какие-либо ресурсы на самом простом пути, чтобы НЕ доверять всем сертификатам для производственного кода? – whyoz

+0

@whyoz извините, не ресурс. – jowett

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

И просто позвонить в SSLConection.allowAllSSL(); перед вызовом метода сервера через KSOAP2. Это все, работает для меня. Все SSL-сертификаты принимаются, и я могу использовать KSOAP2 с протоколом https.

+0

Спасибо за добавление вашего фрагмента тоже – rallat

+0

Идеальное простое решение! Спасибо :) – OmarBizreh

+0

рад помочь! :-) – Neonigma