KSOAP2android与HTTPS

KSOAP2android与HTTPS,android,soap,https,ksoap2,Android,Soap,Https,Ksoap2,我正在使用KSOAP2在Android中管理SOAP,但它使用https作为SOAP url,我收到了以下错误:javax.net.ssl.SSLException:不受信任的服务器证书 这是一个正常错误,因为证书不受信任,但有人知道如何解决此错误吗? 我无法管理证书,因为它来自其他公司,我无权更改它 谢谢我自己找到了答案 在ServiceConnectionSE.java上,为接受不受信任的证书添加以下内容: private TrustManager[] trustAllCerts = ne

我正在使用KSOAP2在Android中管理SOAP,但它使用https作为SOAP url,我收到了以下错误:javax.net.ssl.SSLException:不受信任的服务器证书
这是一个正常错误,因为证书不受信任,但有人知道如何解决此错误吗? 我无法管理证书,因为它来自其他公司,我无权更改它


谢谢我自己找到了答案

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

    • 我还不能发表评论,所以我将我的评论发布到rallat answer这里。他的解决方案可行,但需要进一步解释。要使用ssl运行ksoap2,请执行以下操作:

    • ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar
      放入项目中
    • 从(ksoap2存储库)下载ksoap2源代码
    • 复制
      HttpTransportSE.java
      ServiceConnectionSE.java
      (我还需要复制
      Transport.java
      ServiceConnection.java
      HeaderProperty.java
      )。从这些文件中删除导入,并确保它们使用您的文件(而不是从
      ksoap2.jar导入)
    • 使用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) {
                }
            }
        };
        
        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());
        
        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);
        }
        
    • 在您的代码中,只需使用:

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

    • 教程中的其他内容创建一个新类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()); 
          } 
      
      } 
      

      再次检查这个问题,我发现了一个更干净的解决方案。无需修改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());
              }
          }
      }
      

      只需调用
      sslconnection.allowAllSSL()在通过KSOAP2调用服务器方法之前。就这些,对我有用。所有SSL证书都被接受,我可以使用KSOAP2和https协议。

      @Zirael…感谢您的帮助…我很想知道,而不是想知道是否有安全证书…我如何进一步处理它…无法使用提供的链接找到ksoap的源-它已断开。=\更新:我找到了。。。仅使用:如何在ksoap2中包含ssl?你能检查一下吗-严重+1 jowett…我把你的代码放在我活动的末尾,我所要做的就是让FakeX509TrustManager保持静态,然后它就通过了…我已经读了很多帖子,这是迄今为止最容易实现的。注意这篇文章先前答案上的日期…说得够多了。您是否有关于不信任生产代码的所有证书的最简单方法的资源?@whyoz抱歉,没有资源。感谢您将代码片段添加到完美的简单解决方案中!谢谢:)不过这是一个非常危险的解决办法。使您暴露于MITM攻击。