KSOAP 2 Android с HTTPS - PullRequest
       40

KSOAP 2 Android с HTTPS

12 голосов
/ 09 августа 2010

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

Спасибо

Ответы [ 4 ]

16 голосов
/ 23 сентября 2013

Еще раз проверив эту проблему, я нашел для меня более чистое решение.Модификация файлов 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.

10 голосов
/ 10 февраля 2011

Я пока не могу комментировать, поэтому я публикую свои комментарии к ответу 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);
    

Другие вещи, как в учебниках

4 голосов
/ 08 апреля 2013

Создайте новый класс 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()); 
    } 

} 
4 голосов
/ 11 августа 2010

Я нахожу ответ самостоятельно

  • на 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());
    
...