首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取SSLHandShakeException

获取SSLHandShakeException
EN

Stack Overflow用户
提问于 2013-04-02 10:51:55
回答 2查看 22.2K关注 0票数 11

当我访问wsdl url时,我得到了android中的异常。

代码语言:javascript
复制
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

我使用了ksoap2库来执行WSDL文件。

我也实现了认证课程,但我也遇到了同样的问题。

如果有什么解决办法,请告诉我。

我正在使用这两个类进行认证:

AndroidInsecureHttpsServiceConnectionSE类:

代码语言:javascript
复制
    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类:

代码语言:javascript
复制
 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;
    }
}

在使用了这些证书类之后,我得到了相同的异常。

请帮帮我..。

谢谢.)

EN

回答 2

Stack Overflow用户

发布于 2014-01-29 09:29:54

您应该有一个经过授权的SSL证书--它可以解决问题,这是解决问题的最佳方法。

如果不是,你必须工作一点:

其概念是,当使用SSL时,android比通常要难一些,而且您应该在Android上拥有证书权限,因此,您应该在Android上拥有一个基本的密钥存储库(就像google商店,但是是免费的,并且是在您自己的Android上),并且通过一些基本的操作使您自己的密钥库可信。

  1. 在服务器上找到您的证书,并使用私钥导出(您将拥有管理权限)。这可以通过从start->run + certmgr.msc运行来完成.查找“可信根证书颁发机构”。找到您的证书并进行导出( keytool可以加载现有的pfx证书。在*.cer类型的证书上,可能会出现一些小问题。
  2. 你应该有一个钥匙工具。您可以在可以安装的http://keytool.sourceforge.net/上找到解释,但我更喜欢以下命令:这是通过帮助-软件更新-查找和安装-搜索新功能.单击“新建远程站点”并在名称和URL中添加http://keytool.sourceforge.net/update,并确保其选中。命中终点。
  3. 添加一个新的密钥存储库,并加载您的证书(使用pcs12协议,选择您可以记住的密码)。
  4. 需要添加的代码如下:http://developer.android.com/training/articles/security-ssl.html#UnknownCa
  5. 你应该把你的联系联系起来。您使用HttpTransportSE::ServiceConnection::setSSLSocketFactory就像使用示例一样。https://code.google.com/p/androidzon/source/browse/Androidzon/src/it/marco/ksoap2/HttpTransportSE.java?r=77 (只需创建自己的新函数,并将其连接到web服务。如果不能工作,请删除?wsdl)

祝好运!

票数 2
EN

Stack Overflow用户

发布于 2013-04-03 05:22:23

此错误是由于与服务器建立信任方面的问题造成的。大多数情况下,您的信任库没有服务器提交的证书。以下两个问题的答案可能对你有帮助。

1- How Can I Access an SSL Connection Through Android?

2- Certificate is trusted by PC but not by Android

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15762249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档