给apk添加ssl证书怎么操作?安卓app配置https证书教程
- 虚拟主机
- 2026-06-14
- 6
在Android应用开发中,为APK添加或配置SSL证书主要涉及两个层面:一是确保应用能安全地通过HTTPS与服务器通信(客户端验证),二是让应用信任特定的自签名证书或内部CA证书(证书绑定或信任存储),由于Android 7.0(API 24)引入了网络安全性配置(Network Security Configuration),现代开发中通常不再直接修改APK内部结构,而是通过配置文件来管理证书信任策略。
理解证书信任机制
在Android系统中,应用默认信任系统预装的CA证书,如果服务器使用的是自签名证书或由私有CA签发的证书,应用默认会拒绝连接,抛出SSLHandshakeException,为了解决这个问题,我们需要将自定义证书“添加”到应用的信任存储中。
准备证书文件
你需要拥有服务器的SSL证书文件,通常格式为.pem或.crt,如果是自签名证书,你需要从服务器导出公钥证书。
- 操作建议:将证书文件放置在项目的 res/raw/ 目录下,将证书命名为 my_server_cert.pem,则路径为 res/raw/my_server_cert.pem。
- 注意:确保证书编码为PEM格式(Base64编码,以-----BEGIN CERTIFICATE-----开头),如果是DER格式,需先转换。
配置网络安全性配置(Network Security Configuration)
这是Android 7.0及以上版本推荐的标准做法,通过XML配置文件,你可以指定应用信任哪些额外的证书。
创建配置文件
在 res/xml/ 目录下创建一个名为 network_security_config.xml 的文件(如果不存在则新建)。

编写配置内容
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <!-默认情况下,应用只信任系统CA证书 --> <domain-config cleartextTrafficPermitted="false"> <!-指定你的服务器域名 --> <domain includeSubdomains="true">yourdomain.com</domain> <!-添加额外的信任锚点(即你的自定义证书) --> <
;trust-anchors> <!-信任系统预装的CA --> <certificates src="system" /> <!-信任应用内提供的自定义证书 --> <certificates src="@raw/my_server_cert" /> </trust-anchors> </domain-config> </network-security-config>
- src="system":保留对系统默认CA的信任。
- src="@raw/my_server_cert":引用 res/raw/ 目录下的证书文件,注意这里不需要写扩展名 .pem。
在AndroidManifest.xml中引用配置
打开 AndroidManifest.xml,在 <application> 标签中添加 android:networkSecurityConfig 属性。
<application android:networkSecurityConfig="@xml/network_security_config" ... > <!-其他配置 --> </application>
处理旧版本Android设备(API < 24)
虽然大多数现代设备已升级,但为了兼容性,有时仍需考虑旧版本,Android 7.0以下版本不支持 network_security_config,通常需要通过代码动态配置 TrustManager,但这存在安全风险且代码复杂。

替代方案:使用OkHttp或Retrofit自定义SSLContext
如果你使用OkHttp作为网络库,可以在构建客户端时自定义SSL上下文:
// 1. 从资源加载证书 InputStream certInput = context.getResources().openRawResource(R.raw.my_server_cert); CertificateFactory cf = CertificateFactory.getInstance("X.509"); Certificate cert = cf.generateCertificate(certInput); certInput.close(); // 2. 创建信任管理器 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry("ca", cert); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(keyStore); // 3. 创建SSLContext SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); // 4. 应用到OkHttp OkHttpClient client = new OkHttpClient.Builder() .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0]) .build();
证书绑定(Certificate Pinning)的高级选项
除了简单的信任添加,生产环境常使用证书绑定,即应用不仅信任证书,还验证证书的指纹(Hash),防止中间人攻破即使使用了杜撰的CA证书。
在 network_security_config.xml 中可以使用 <pin-set> 实现:

<domain-config> <domain includeSubdomains="true">yourdomain.com</domain> <pin-set> <!-指定证书的SHA-256指纹 --> <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin> <!-允许备用证书用于轮换 --> <pin digest="SHA-256">WoiWRyIOVNa9ihaBciRSC7XHczli5S2Z4CHvgx7u8F0=</pin> </pin-set> </domain-config>
常见问题排查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| SSLHandshakeException: Trust anchor for certification path not found | 未正确配置 network_security_config 或证书路径错误 | 检查 res/xml/network_security_config.xml 是否正确引用了 @raw/ 下的证书;检查域名是否匹配。 |
| 应用崩溃或网络请求无响应 | 证书格式错误(如DER格式未转换) | 确保证书为PEM格式;使用 openssl x509 -in cert.der -inform DER -out cert.pem 转换。 |
| 在Android 7.0以下设备失效 | 未实现代码层面的TrustManager配置 | 针对低版本设备使用OkHttp/Retrofit自定义SSLContext,或考虑放弃支持旧版本。 |
| 证书轮换后应用无法连接 | 使用了硬编码的指纹且未更新 | 在 <pin-set> 中配置多个 <pin> 条目,包含旧证书和新证书的指纹,实现平滑过渡。 |
相关问题与解答
问题1:为什么在Android 7.0及以上版本中,直接修改系统CA证书存储(如将证书放入/system/etc/security/cacerts)对普通应用无效?
解答:
从Android 7.0开始,Google引入了应用隔离的沙箱机制,默认情况下,应用只能信任其所在用户空间(User Space)内的CA证书,即系统预装的证书和应用自身配置的证书,即使你拥有Root权限并将证书放入了系统目录,普通应用(非系统应用)也不会自动信任它,除非应用明确声明信任该证书或通过 network_security_config 显式添加,这是为了增强安全性,防止恶意应用利用系统级证书进行中间人攻破,标准做法是通过 network_security_config 在应用层面管理信任链。
问题2:如果我的服务器证书是由私有CA签发的,且该CA证书本身也未被任何设备信任,我应该如何配置才能让应用信任它?
解答:
你需要信任整个证书链,在 network_security_config.xml 中,<trust-anchors> 标签下可以添加多个证书,你需要添加两个证书:
- 根CA证书(Root CA):私有CA的根证书。
- 中间CA证书(Intermediate CA):如果服务器证书是由中间CA签发的,而中间CA又由根CA签发,建议同时添加根CA和中间CA,或者只添加根CA(取决于证书链的完整性)。
配置示例如下:
<trust-anchors> <certificates src="system" /> <certificates src="@raw/root_ca_cert" /> <certificates src="@raw/intermediate_ca_cert" /> </trust-anchors>
确保将 root_ca_cert.pem 和 intermediate_ca_cert.pem 都放入 res/raw/ 目录,并在配置中正确引用,这样,应用就能验证从服务器证书到根CA的完整信任链。