Android自签名证书:找不到证书路径的信任锚 [英] Android self signed certificate: Trust anchor for certification path not found

查看:1901
本文介绍了Android自签名证书:找不到证书路径的信任锚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这个主题在很多地方都讨论过,但是在经历了几乎所有主题之后,我决定创建我的第一个StackOverflow问题...

I know this subject is discussed in many places, but after I went through almost all of them, I have decided to create my first StackOverflow question...

问题是由于以下原因造成的:

我想连接到安全的Web服务(https),该服务使用证书来限制访问,并使用用户名/密码来对用户进行身份验证.所以我有一个客户端证书(p12文件)和一个服务器证书(pem或der文件).我尝试使用HttpURLConnection类,因为据我所知,Android将不再支持Apache库.

I want to connect to a secured webservice (https) that use a certificate to restrict the access, and a username/password to authenticate the user. So i have a client cert (p12 file) and a server cert (pem or der file). I try to use the HttpURLConnection class, because from what I've heard, Apache library will no more be supported on Android.

这就是我的实现(serverCert和clientCert是文件的完整路径):

So this is my implementations (serverCert and clientCert are the full path to my files):

        // Load CAs from our reference to the file
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream caInput = new BufferedInputStream(new FileInputStream(serverCert));
        X509Certificate serverCertificate;

        try {
            serverCertificate = (X509Certificate)cf.generateCertificate(caInput);
            System.out.println("ca=" + serverCertificate.getSubjectDN());
        } finally {
            caInput.close();
        }
        Log.d(TAG, "Server Cert: " + serverCertificate);

        // Create a KeyStore containing our trusted CAs
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null);
        trustStore.setCertificateEntry("my ca", serverCertificate);

        //Load the Client certificate in the keystore
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        FileInputStream fis = new FileInputStream(clientCert);
        keyStore.load(fis,CLIENT_PASSWORD);

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

        //Build the SSL Context
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(keyStore, pref.getString(Constants.clientCertificatePassword, "").toCharArray

());


    //Create the SSL context
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
...
    //And later, we use that sslContext to initiatize the socketFactory

                urlConnection = (HttpsURLConnection) requestedUrl.openConnection();
         urlConnection.setSSLSocketFactory(CertificateManager.getInstance().getSslContext().getSocketFactory());
...

因此,我可以创建我的SSLContext,并显示我的两个证书内容.但是当我尝试执行HTTPS连接时,出现以下异常:

So i can create my SSLContext, and display my two certificates content. But when i try to execute my HTTPS connection, I get the following exception:

09-23 13:43:30.283:W/System.err(19422):javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:找不到证书路径的信任锚.

09-23 13:43:30.283: W/System.err(19422): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

你们中的一个遇到过以下错误吗?您有什么解决方案?

Does one of you ever met the following error? What was your solution?

这些是我浏览过的网站(没有成功):

These are the website i went through (without success):

http://blog.chariotsolutions.com/2013/01/https -with-client-certificates-on.html

http://nelenkov.blogspot.ch/2011/12/using-custom-certificate-trust-store-on.html

推荐答案

在您的代码中,您正在创建和初始化SSLContext,但没有使用它.也许您应该替换:

In your code your are creating and initializing a SSLContext but not using it. Maybe you should replace :

urlConnection.setSSLSocketFactory(CertificateManager.getInstance().getSslContext().getSocketFactory());

作者

urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());

我还建议您尽可能将选项-Djavax.net.debug=all传递给JVM.它将在标准输出上打印有关SSL连接和握手的详细信息.

I also suggest you if possible to pass the option -Djavax.net.debug=all to the JVM. It will print detailed information about the SSL connection and handshake on the standard output.

这篇关于Android自签名证书:找不到证书路径的信任锚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆