Android自签名证书:找不到证书路径的信任锚

Posted

技术标签:

【中文标题】Android自签名证书:找不到证书路径的信任锚【英文标题】:Android self signed certificate: Trust anchor for certification path not found 【发布时间】:2013-09-28 08:58:09 【问题描述】:

我知道这个话题在很多地方都有讨论,但是在我几乎浏览了所有这些之后,我决定创建我的第一个 *** 问题......

问题如下:

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

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

        // 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 连接时,出现以下异常:

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

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

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

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

【问题讨论】:

我也试过这个解决方案 (nelenkov.blogspot.ch/2011/12/…) ,但仍然是同样的消息... 是不是服务器配置不好? 嘿,好久不见,你找到解决办法了吗?我确实有同样的问题。我有一个 pem 和一个 p12 文件。 【参考方案1】:

在您的代码中,您正在创建和初始化 SSLContext 但不使用它。也许你应该更换:

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

通过

urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());

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

【讨论】:

以上是关于Android自签名证书:找不到证书路径的信任锚的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 项目上找不到证书路径的信任锚

CertPathValidatorException:找不到证书路径的信任锚 - Retrofit Android

Android java.security.cert.CertPathValidatorException:找不到证书路径的信任锚

android https遇到自签名证书/信任证书

如何信任 Android 上的自签名证书?

CertPathValidatorException:找不到证书路径的信任锚