Android:无法使用 Entrust 证书建立 HTTPS 连接

Posted

技术标签:

【中文标题】Android:无法使用 Entrust 证书建立 HTTPS 连接【英文标题】:Android: Couldn't establish HTTPS connection using Entrust certificate 【发布时间】:2017-03-10 15:50:03 【问题描述】:

我特别想建立到这个网站的 HTTPS 连接,https://elearning.utp.edu.my/

我从 SSL 工具检查了网站使用 Entrust_L1K 证书,然后我从 Chrome 浏览器导出证书文件。

我尝试使用android开发者网站提供的代码。

 try 
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = mContext.getResources().openRawResource(R.raw.entrust_l1k);
            Certificate ca;
            try 
                ca = cf.generateCertificate(caInput);
                System.out.println("ca = " + ((X509Certificate) ca).getSubjectDN());
             finally 
                caInput.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);

            HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
            urlConnection.setConnectTimeout(7000);
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoInput(true);
            urlConnection.connect();

            int responseCode = urlConnection.getResponseCode();

            switch (responseCode) 
                case HttpsURLConnection.HTTP_OK:

                    InputStream in = urlConnection.getInputStream();

                    Scanner scanner = new Scanner(in);
                    scanner.useDelimiter("\\A");

                    boolean hasInput = scanner.hasNext();
                    if (hasInput) 
                        return scanner.next();
                     else 
                        return null;
                    


                default:
                    return null;
            
         catch (Exception e) 
            e.printStackTrace();
            return null;
        

但是我仍然收到以下错误代码

W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

我尝试了 Stack Overflow 的多种解决方案。

我希望学习在不信任所有证书的情况下连接到 HTTPS 的最佳实践。 如果有人可以指导我,将不胜感激。

编辑 1:显然,当我使用 Firefox 单击“登录”时,它会提示显示“elearning.utp.edu.my 使用无效的安全证书”的警告。 但是,我可以使用 Chrome 与网站建立“安全”连接。 网址如下:https://elearning.utp.edu.my/login/index.php

【问题讨论】:

【参考方案1】:

L1K 证书由 Root G2 证书签名,因此您也应该将其添加到密钥库/信任管理器中:

caInput = mContext.getResources().openRawResource(R.raw.entrust_root_g2);
try 
    ca = cf.generateCertificate(caInput);
    System.out.println("ca = " + ((X509Certificate) ca).getSubjectDN());
 finally 
    caInput.close();


// Use the same keystore.
// Mind the different alias.

keyStore.setCertificateEntry("ca2", ca);

您必须将SSLContext 链接到该连接。您可能希望在实例化连接对象后立即执行此操作:

urlConnection.setSSLSocketFactory(context.getSocketFactory());

注意:虽然您声明要连接到特定网站,但请注意此 TLS 配置将拒绝任何其他证书。例如。如果您将 URL 更改为 https://***.com/,则 TLS 握手将失败。如果您想接受自定义证书以及默认证书,请查看此处:https://***.com/a/24561444/2657100

【讨论】:

谢谢!我跟着你的步骤,它现在正在工作:)

以上是关于Android:无法使用 Entrust 证书建立 HTTPS 连接的主要内容,如果未能解决你的问题,请参考以下文章

在 Node express 应用程序中安装 Entrust SSL 证书

为啥 APNS 需要 Entrust ssl 证书的 ssl

无法使用主题备用名称证书为 SSL/TLS 安全通道建立信任关系

使用多域 SSL SAN 证书无法在 Chrome 中建立 wss websocket 连接

Adobe AIR-无法为签名者建立有效的证书链

发生ssl错误 无法建立到该服务器的安全连接