📅  最后修改于: 2023-12-03 15:24:41.372000             🧑  作者: Mango
在Android应用程序中,当使用HTTPs请求数据时,会进行SSL认证来确保网络安全。SSL认证需要建立信任链路(Trust Path),也就是证书链,如果出现异常则会导致SSL认证失败,导致无法进行网络请求。
SSL(HTTPs)认证路径异常的表现包括但不限于以下几种:
在捕获到SSL(HTTPs)认证路径异常时,需要查看异常信息来确定具体的异常原因。异常信息一般包括异常类型和异常信息详情。根据异常信息详情,可以知道是否是证书链问题,如果是,还需要判断是什么原因导致证书链不被信任,是否是证书过期、证书颁发机构不受信任等。
try {
// 进行网络请求
} catch (SSLException e) {
e.printStackTrace();
}
当出现证书不被信任时,可以通过导入证书的方式来解决。证书可以是服务器端的证书,也可以是中间证书。我们需要用到Bouncy Castle库,这是一个第三方的加密库,需要在项目中引入。
获取服务器端证书的方式有多种,这里以将证书放在assets文件夹下为例。
// 创建Bouncy Castle库的证书工厂
Security.insertProviderAt(new BouncyCastleProvider(), 1);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
InputStream inputStream = context.getAssets().open("server.crt");
X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(inputStream);
// 将证书添加至信任证书管理器
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("server", cert);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
// 进行HTTPs请求
URL url = new URL("https://example.com/");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) conn;
httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
有些情况下,服务器并不直接提供证书,而是提供了一个中间证书(Intermediate Certificate),需要将中间证书和根证书一起导入。
// 获取根证书
InputStream rootInputStream = context.getAssets().open("root.crt");
X509Certificate rootCert = (X509Certificate) certificateFactory.generateCertificate(rootInputStream);
// 获取中间证书
InputStream intermediateInputStream = context.getAssets().open("intermediate.crt");
X509Certificate intermediateCert = (X509Certificate) certificateFactory.generateCertificate(intermediateInputStream);
// 将证书添加至信任证书管理器
keyStore.setCertificateEntry("root", rootCert);
keyStore.setCertificateEntry("intermediate", intermediateCert);
禁用证书校验虽然可以让应用程序请求到数据,但同时也会将网络请求变得不安全。这种方式只应在开发和调试阶段使用,不能在正式上线的应用程序中使用。
// 禁用证书校验
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}}, new SecureRandom());
SSL(HTTPs)认证路径异常是Android应用程序中常见的问题,应该尽早发现并解决。处理SSL(HTTPs)认证路径异常的方法多种多样,需要根据具体情况选择合适的处理方式。在开发和调试阶段,可以使用禁用证书校验的方式来快速检查应用程序的逻辑是否正确,但同时也需要注意安全问题。