带有 HTTPS 的 KSOAP 2 Android

发布于 2024-09-13 16:35:21 字数 187 浏览 4 评论 0原文

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

谢谢

I am using KSOAP2 to manage SOAP in Android but it use https for the SOAP url and I am getting this error: javax.net.ssl.SSLException: Not trusted server certificate
A normal error because the certificate is untrusted, but anyone knows how to workaround with this error?
I can not manage the certificate because is from a other company and I don't have access to change it.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

停滞 2024-09-20 16:35:21

再次检查这个问题,我发现了一个更干净的解决方案。无需修改 KSOAP2 文件。

在您的项目中,链接 ksoap2-android-assemble-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());
        }
    }
}

在通过 KSOAP2 调用服务器方法之前,只需调用 SSLConection.allowAllSSL(); 即可。这一切,对我有用。所有 SSL 证书都被接受,我可以使用带有 https 协议的 KSOAP2。

Checking again this problem, I've discovered a more clean solution for me. No KSOAP2 files modification needed.

In your project, link the ksoap2-android-assembly-3.0.0-jar, with no modifications.

Next, create a file named SSLConnection.java with this code:

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

And just call to SSLConection.allowAllSSL(); before calling a server method via KSOAP2. It's all, works for me. All SSL certificates are accepted and I can use KSOAP2 with https protocol.

迷雾森÷林ヴ 2024-09-20 16:35:21

我还不能发表评论,所以我将我的评论发布到这里的 rallat 答案。他的解决方案有效,但需要进一步解释。要使用 ssl 运行 ksoap2:

  1. ksoap2-android-assemble-2.5.2-jar-with-dependency.jar 放入项目中
  2. https://github.com/mosabua/ksoap2-android/tree/(ksoap2 存储库)
  3. 复制 HttpTransportSE.java, ServiceConnectionSE.java(我还需要复制 Transport.javaServiceConnection.javaHeaderProperty.java)。删除这些文件中的导入并确保它们使用您的文件(不是从 ksoap2.jar 导入)
  4. 使用 rallat 答案(我复制粘贴它):

    • ServiceConnectionSE.java 添加此内容以接受不受信任的证书:

      私有 TrustManager[] trustAllCerts = new TrustManager[] {
          新的 X509TrustManager() {
              公共 java.security.cert.X509Certificate[] getAcceptedIssuers() {
                  返回空值;
              }
              公共无效检查客户端信任(
                  java.security.cert.X509Certificate[] 证书,字符串 authType) {
              }
              公共无效检查服务器可信(
                  java.security.cert.X509Certificate[] 证书,字符串 authType) {
              }
          }
      };
      
    • 然后使用这个构造函数
      允许不受信任的证书,并且不允许
      已验证的主机名:

      public ServiceConnectionSE(String url) throws IOException {
          尝试 {
              SSLContext sc = SSLContext.getInstance("TLS");
              sc.init(null, trustAllCerts, new java.security.SecureRandom());
              HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
          } catch (异常 e) {
              e.getMessage();
          }
          连接 = (HttpsURLConnection) 新 URL(url).openConnection();
          ((HttpsURLConnection) 连接).setHostnameVerifier(new AllowAllHostnameVerifier());
      }    
      
    • 第二个构造函数

      public ServiceConnectionSE(Proxy proxy, String url) throws IOException {
          尝试 {
              SSLContext sc = SSLContext.getInstance("TLS");
              sc.init(null, trustAllCerts, new java.security.SecureRandom());
              HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
           } catch (异常 e) {
              e.getMessage();
           }
           连接 = (HttpsURLConnection) 新 URL(url).openConnection();
          ((HttpsURLConnection) 连接).setHostnameVerifier(new AllowAllHostnameVerifier());
      
          连接.setUseCaches(false);
          连接.setDoOutput(true);
          连接.setDoInput(true);
      }
      
  5. 在您的代码中只需使用:

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

教程中的其他内容

I can't comment yet so i post my comments to rallat answer here. His solution works but it needs further explanations. To run ksoap2 with ssl:

  1. Put ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar in a project
  2. Download ksoap2 sources from https://github.com/mosabua/ksoap2-android/tree/ (ksoap2 repository)
  3. Copy HttpTransportSE.java, ServiceConnectionSE.java (I also needed to copy Transport.java, ServiceConnection.java and HeaderProperty.java). Delete imports from those files and make sure that they use your files (not imports from ksoap2.jar)
  4. Use rallat answer ( I copy-pasted it):

    • ServiceConnectionSE.java add this for accept untrusted certificate:

      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) {
              }
          }
      };
      
    • then use this constructors to
      allow untrusted certificates and not
      verified hostnames:

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

      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. In your code just use:

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

Other things as in tutorials

盗琴音 2024-09-20 16:35:21

我自己找到答案

  • 在 ServiceConnectionSE.java 上添加此内容以接受不受信任的证书:

    私有 TrustManager[] trustAllCerts = 新 TrustManager[]{
        新的 X509TrustManager() {
            公共 java.security.cert.X509Certificate[] getAcceptedIssuers() {
                返回空值;
            }
            公共无效检查客户端信任(
                java.security.cert.X509Certificate[] 证书,字符串 authType) {
            }
            公共无效检查服务器可信(
                java.security.cert.X509Certificate[] 证书,字符串 authType) {
            }
        }
    };
    
  • 然后在构造函数中添加此内容以允许不受信任的证书和未经验证的主机名:

    <前><代码>尝试{
    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (异常 e) {
    e.getMessage();
    }
    连接 = (HttpsURLConnection) 新 URL(url).openConnection();
    ((HttpsURLConnection) 连接).setHostnameVerifier(new AllowAllHostnameVerifier());

I find the answer by myself

  • on ServiceConnectionSE.java add this for accept untrusted certificate:

    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) {
            }
        }
    };
    
  • then in the constructor add this to allow untrusted certificates and not verified hostnames:

        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());
    
蘸点软妹酱 2024-09-20 16:35:21

创建一个新类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()); 
    } 

} 

Create a new class FakeX509TrustManager to handle the certificate problem,

    FakeX509TrustManager.allowAllSSL();
    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

The new created class is as the following:

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

} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文