Android SSL-CertPathValidator异常

Android SSL-CertPathValidator异常,android,ssl,tomcat7,Android,Ssl,Tomcat7,我的HTTPS服务托管在TomCat中(.keystore是在JDK bin中的keytool的帮助下创建的) 服务器证书是自签名的,并通过将其安装在受信任的根权限中使其成为受信任的 我可以通过浏览器访问该服务,但无法通过Android访问该服务。我是J2EE的初学者 host.cert(放置在资产目录中)是使用OpenSSL创建的 我正在使用Android开发者网站上的代码片段 try { // Load CAs from an InputStream

我的HTTPS服务托管在TomCat中(.keystore是在JDK bin中的keytool的帮助下创建的)

服务器证书是自签名的,并通过将其安装在受信任的根权限中使其成为受信任的

我可以通过浏览器访问该服务,但无法通过Android访问该服务。我是J2EE的初学者

host.cert(放置在资产目录中)是使用OpenSSL创建的

我正在使用Android开发者网站上的代码片段

        try {
            // Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crt

            InputStream inn=getAssets().open("host.cert");

            Certificate ca;
            try {
                ca = cf.generateCertificate(inn);
                Log.i("TEST","ca=" + ((X509Certificate) ca).getSubjectDN());
            } finally {
                inn.close();
            }

// Create a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

// Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

// Create an SSLContext that uses our TrustManager
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, tmf.getTrustManagers(), null);

// Tell the URLConnection to use a SocketFactory from our SSLContext
            URL url = new URL("https://192.168.56.1:8443/RestHTTPS/JavaCodeGeeks/AuthorService/authors/");
            HttpsURLConnection urlConnection =
                    (HttpsURLConnection)url.openConnection();
            urlConnection.setSSLSocketFactory(context.getSocketFactory());
            InputStream in = urlConnection.getInputStream();

            byte arr[]=new byte[in.available()];
            in.read(arr);

            String str=new String(arr);
            Log.i("TEST",str);

        }catch (Exception e){
            Log.e("TEST",e.toString());
            e.printStackTrace();
        }

我知道已经有人问了这个问题,但我找不到解决方案。

我会为仍然面临这个问题的人发布解决方案

主要注意三件事(已在中说明)

  • 创建自定义信任管理器以绕过默认信任管理器
  • 手动验证主机名是否可接受
  • 切勿使用“localhost”或“127.0.0.1”进行测试,而应使用电脑的IP地址
这是完整的代码

try {

            // Things to Note 1 : Bypass default Trust Managers
            TrustManager[] byPassTrustManagers = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }

                public void checkClientTrusted(X509Certificate[] chain, String authType) {
                }

                public void checkServerTrusted(X509Certificate[] chain, String authType) {
                }
            }};

            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream inn = getAssets().open("keystore.cer");
            Certificate ca;
            try {
                ca = cf.generateCertificate(inn);
                Log.i("TEST", "ca=" + ((X509Certificate) ca).getSubjectDN());
            } finally {
                inn.close();
            }


            String keyStoreType = "BKS";
            KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, byPassTrustManagers, null);

            // Things to Note 2 : Don't use "localhost" ,instead use IP
            URL url = new URL("https://192.168.56.1:8443/RestHTTPS/JavaCodeGeeks/AuthorService/authors");
            HttpsURLConnection urlConnection =
                    (HttpsURLConnection) url.openConnection();

            urlConnection.setSSLSocketFactory(context.getSocketFactory());

            // Things to Note 3 : Allow all host
            urlConnection.setHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            Log.i("TEST", urlConnection.getResponseMessage() + "");

            InputStream in = urlConnection.getInputStream();

            InputStreamReader isw = new InputStreamReader(in);

            int data = isw.read();
            String str = "";
            while (data != -1) {
                char current = (char) data;
                data = isw.read();
                str += current;
            }

            Log.i("TEST", "" + str);

        } catch (Exception e) {
            Log.e("TEST", e.toString());
            e.printStackTrace();
        }