android 适应CA证书
要使 Android 应用适应和信任自签名 CA 证书,尤其是在开发、测试或内部网络中,有几种常见的方式可以配置应用使其信任自定义 CA 证书。通常这涉及到为应用定义网络安全配置或调整系统设置。
方法 1: 使用网络安全配置(Network Security Configuration)
从 Android 7.0(API 24)开始,你可以在应用中通过网络安全配置文件来信任自定义的 CA 证书。
配置步骤
-
创建
network_security_config.xml
文件在
res/xml
目录下创建一个新的 XML 文件,例如network_security_config.xml
,定义证书信任规则:<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <!-- 信任的域名或 IP 地址 --> <domain includeSubdomains="true">yourdomain.com</domain> <!-- 引用自定义 CA 证书 --> <certificates src="@raw/my_ca"/> </domain-config> </network-security-config>
-
引用 CA 证书
将你的 CA 证书(
my_ca.crt
)文件放入res/raw/
目录下。 -
应用网络安全配置
在
AndroidManifest.xml
文件的<application>
标签内引用刚创建的网络安全配置文件:<application android:networkSecurityConfig="@xml/network_security_config" ...> ... </application>
方法 2: 为特定连接手动添加 CA 证书
如果无法使用网络安全配置文件,或是在 Android 7.0 以下版本,可以使用以下代码手动为特定的 HTTPS 连接添加 CA 证书。
配置步骤
-
将 CA 证书导入到
TrustManager
将
.crt
文件转换为InputStream
,并将其加载到应用的TrustManager
中。 -
示例代码
// 将 CA 证书加载到 TrustManager 中 public SSLSocketFactory getSSLSocketFactory(Context context) throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream caInput = new BufferedInputStream(context.getResources().openRawResource(R.raw.my_ca)); // 证书放在res/raw Certificate ca; try { ca = cf.generateCertificate(caInput); } finally { caInput.close(); } KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(keyStore); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); return sslContext.getSocketFactory(); }
-
应用 SSLSocketFactory 到
OkHttpClient
或HttpsURLConnection
将上述创建的
SSLSocketFactory
应用于 HTTP 客户端。OkHttpClient client = new OkHttpClient.Builder() .sslSocketFactory(getSSLSocketFactory(context), (X509TrustManager) tmf.getTrustManagers()[0]) .build();
注意事项
- 生产环境避免使用自签名 CA 证书:在生产环境中,建议始终使用权威机构颁发的 CA 证书。
- 限制证书的应用范围:确保
network_security_config
或信任的 CA 证书仅应用于特定的开发或测试阶段,以避免潜在的安全风险。
另外,只配置方法 1 中的第一步和第三步也可以生效,但前提是你的目标 CA 证书已经安装在 Android 系统的受信任证书存储中(即设备上已信任该 CA),或者证书由权威 CA 签发而不需要自定义导入。
在这种情况下,network_security_config.xml 只需定义域名和连接策略,因为系统会自动识别并信任已安装的系统证书。通过 network_security_config 配置文件,应用程序会遵循所定义的域配置和证书策略,但无需额外导入 .crt 文件。
补充说明
使用系统证书:当你的自签名证书已在设备的系统证书存储中信任,network_security_config 配置会直接生效。
仅适用于自定义证书的场景:当你需要使用一个应用独有的自签名证书,并且该证书不在系统证书存储中时,才需要将 .crt 文件放入 res/raw 目录并引用。
如果仅在应用内配置 network_security_config.xml 并指向正确的域,通常在设备上已信任的证书环境下就可以正常工作。