Android:无法使用Entrust证书

时间:2017-03-10 15:50:04

标签: android https

我想与此网站建立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 个答案:

答案 0 :(得分: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://stackoverflow.com/,则TLS握手将失败。如果您想接受自定义证书以及默认证书,请查看此处:https://stackoverflow.com/a/24561444/2657100