使用android Nougat中的自签名证书通过https连接时的SSL握手异常 [英] SSL handshake exception while connecting over https using self signed certificate in android Nougat

查看:183
本文介绍了使用android Nougat中的自签名证书通过https连接时的SSL握手异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Android应用程序中,我通过https连接。我正在使用自签名证书进行连接。
它正在api级别24以下的设备上工作(在android nougat之前)。但是在Android Nougat上它会抛出SSL握手异常:

In my android application i connect over https. I am using a self signed certificate to connect. It is working on devices below api level 24 (before android nougat).But on android Nougat it throws the SSL Handshake exception :


javax.net.ssl.SSLHandshakeException:
java.security.cert.CertPathValidatorException:找不到
认证路径的信任锚。

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

这是我通过https连接的方式: -

This is how i connect over https:-

SSLContext context = null;
    try 
    {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        // Get the raw resource, which contains the keystore with
        // your trusted certificates (root and any intermediate certs)
        InputStream input = new BufferedInputStream(context.getAssets().open(pkcsFilename));
        try {
            // Initialize the keystore with the provided trusted certificates
            // Also provide the password of the keystore
            keyStore.load(input, password.toCharArray());
        } finally {
            input.close();
        }

        KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyFactory.init(keyStore, "".toCharArray());

        // Load CAs from an InputStream
        // (could be from a resource or ByteArrayInputStream or ...)
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        Certificate ca = null;
        input = new BufferedInputStream(context.getAssets().open(certificateFilename));
        try 
        {
            ca = cf.generateCertificate(input);
        }
        finally
        {
            input.close();
        }
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);
        trustStore.setCertificateEntry("server", ca);

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

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

        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();

我尝试了以下链接,但它没有帮助。

I tried the following link, But it does not help.

这是我的网络配置文件。我已将其添加到我的AndroidManifest.xml文件中。

This is my network config file. I have added it in my AndroidManifest.xml file.

    <?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">xyz.com</domain>
        <trust-anchors>
        <certificates src="@raw/root_ca" />
        </trust-anchors>
    </domain-config>
</network-security-config>

请帮我解决这个问题。

推荐答案

我通过添加自定义信任管理器来实现它。初始化SSL上下文 context.init(keyFactory.getKeyManagers(),tmf.getTrustManagers(),null);

i got it working by adding a custom trust managers. While initializing the SSL Context context.init(keyFactory.getKeyManagers(), tmf.getTrustManagers(), null);

I modified it as :

context.init(keyFactory.getKeyManagers(), new TrustManager[] { tm }, null);
TrustManager tm = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    for (int j=0; j<chain.length; j++)
                    {
                        chain[j].checkValidity();
                        try {
                            chain[j].verify(ca.getPublicKey());
                        } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException |
                                SignatureException e) {
                            e.printStackTrace();
                            throw new CertificateException(e.getMessage());
                        }
                    }
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };

我使用服务器证书验证证书。现在它的工作。

i verify the certificate with the server certificate . Now its working .

这篇关于使用android Nougat中的自签名证书通过https连接时的SSL握手异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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