在Android Nougat中使用自签名证书通过https连接时的SSL握手异常

幽映每白日,清辉照衣裳。这篇文章主要讲述在Android Nougat中使用自签名证书通过https连接时的SSL握手异常相关的知识,希望能为你提供帮助。
在我的android应用程序中,我通过https连接。我正在使用自签名证书进行连接。它正在api级别24以下的设备上工作(在android nougat之前)。但是在Android Nougat上它会抛出SSL Handshake异常:

javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:未找到证书路径的信任锚。
【在Android Nougat中使用自签名证书通过https连接时的SSL握手异常】这是我通过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();

我尝试了以下link,但它没有帮助。
这是我的网络配置文件。我已将其添加到AndroidManifest.xml文件中。
< ?xml version="1.0" encoding="utf-8"?> < network-security-config> < domain-config> < domain includeSubdomains="true"> xyz.com< /domain> < trust-anchors> < certificates src="https://www.songbingjia.com/android/@raw/root_ca" /> < /trust-anchors> < /domain-config> < /network-security-config>

请帮我解决这个问题。
答案System.setProperty( “javax.net.ssl.trustStore中”,newKeystoreFile.getAbsolutePath());
simliarly,尝试设置keystorepassword和keypassword属性每次尝试使用上面的属性https://docs.oracle.com/cd/E17802_01/webservices/webservices/reference/tutorials/wsit/doc/WSIT_Security6.html时重启服务器
另一答案我通过添加自定义信任管理器来实现它。在初始化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; } };

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

    推荐阅读