自学内容网 自学内容网

android 适应CA证书

要使 Android 应用适应和信任自签名 CA 证书,尤其是在开发、测试或内部网络中,有几种常见的方式可以配置应用使其信任自定义 CA 证书。通常这涉及到为应用定义网络安全配置或调整系统设置。

方法 1: 使用网络安全配置(Network Security Configuration)

从 Android 7.0(API 24)开始,你可以在应用中通过网络安全配置文件来信任自定义的 CA 证书。

配置步骤
  1. 创建 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>
    
  2. 引用 CA 证书

    将你的 CA 证书(my_ca.crt)文件放入 res/raw/ 目录下。

  3. 应用网络安全配置

    AndroidManifest.xml 文件的 <application> 标签内引用刚创建的网络安全配置文件:

    <application
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
        ...
    </application>
    

方法 2: 为特定连接手动添加 CA 证书

如果无法使用网络安全配置文件,或是在 Android 7.0 以下版本,可以使用以下代码手动为特定的 HTTPS 连接添加 CA 证书。

配置步骤
  1. 将 CA 证书导入到 TrustManager

    .crt 文件转换为 InputStream,并将其加载到应用的 TrustManager 中。

  2. 示例代码

    // 将 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();
    }
    
  3. 应用 SSLSocketFactory 到 OkHttpClientHttpsURLConnection

    将上述创建的 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 并指向正确的域,通常在设备上已信任的证书环境下就可以正常工作。


原文地址:https://blog.csdn.net/fwt336/article/details/143667400

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!