Android证书安装大指南——看这一篇就够啦

6,915 阅读10分钟

大家好,在Android开发和调试的时候,抓包必须给手机安装证书,但是很多同学都卡在这一步。今天给大家带来一篇完整又详细的Android证书指南,证书相关问题只要看这一篇就够了。

本篇文章使用的工具是Reqable:reqable.com

1. 系统版本

随着Android系统的迭代演化,证书策略也在变更。最重要的两个分水岭是7和14版本,我们下面会详细讲。此外,高版本系统为了兼容低版本应用,设计了一个重要的参数targetSdkVersion,原生应用程序开发的时候需要指定这个targetSdkVersion的值。对于证书的验证策略,是根据targetSdkVersion来判定的。

android {  
    defaultConfig {    
        ...    
        targetSdkVersion 21    
        ...  
    }
}

举个例子,如果一个原生应用的targetSdkVersion值是21(Android 5),这个应用装在Android 12系统的设备上运行,和装在Android 5系统设备上运行,两者的证书的验证策略是完全一样的。如果不理解targetSdkVersion的作用也没关系,就按照当前使用设备的系统版本选择合适的证书安装方案就行。

1.1 Android 7前

在Android 7.0(不包括)之前,用户目录证书权限和系统目录证书权限是一样的,所有证书直接安装到用户目录即可。这个最简单,没什么好讲的。

1.2 Android 7- 13

为了安全考虑,Android系统禁用了用户目录证书的权限,用户目录的证书默认不再作为可信任证书,毕竟用户证书任何设备都可以安装。当然,应用程序也可以选择信任用户目录的证书(一般为了方便测试),这要求应用程序开发者在项目源码中进行额外配置,例如Reqable中提供了network_security_config.xml的方案。

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <base-config cleartextTrafficPermitted="true">
    <trust-anchors>
      <certificates src="system" />
      <certificates src="user" />
    </trust-anchors>
  </base-config>
</network-security-config>

1.3 Android 14后

Android 14是另一个重要的分水岭,为了可以动态地更新系统证书,将系统证书迁移到了com.android.conscrypt包中,并通过apex机制进行更新。在之前的版本中,我们会将证书安装到/system/ect/security/cacerts目录。在14版本及之后,还需要安装到/apex/com.android.conscrypt/cacerts目录。

1.4 总结

在这里我们先进行一个小总结:

  • 应用的targetSdkVersion值 < 24,或者设备系统版本 < 7,直接安装到用户证书目录。

  • 应用的targetSdkVersion值 >= 24,且设备系统版本 >= 7,如果要安装到用户证书目录,请在应用源码中配置network_security_config.xml。

  • 系统版本 < 14,安装到系统证书目录,只需要安装到/system/ect/security/cacerts

  • 系统版本 >= 14,安装到系统证书目录,除了安装到/system/ect/security/cacerts,还需要安装到/apex/com.android.conscrypt/cacerts

2. 系统证书

下面我们说一说系统证书的操作以及注意事项。

Android系统证书的格式是hash.0,hash值是根据证书Subject信息生成的,也被称为old-hash。注意,两个不同的证书hash值可能是一样的,如果你想把这两个证书都装进系统,你可以将其中一个改成hash.1,这样就能共存了。如果证书更多的话就是.2 .3等等了。因此,判断两个证书是否相同,请勿根据hash值来判断,而要根据证书指纹。下图就是Reqable(证书菜单 - 查看根证书)中显示的证书指纹信息:

截屏2024-07-10 14.49.10.png

所谓hash.0证书的内容可以是pem格式,也可以是crt格式,拿到这一类证书可以直接将名称改为hash.0,然后导入系统目录即可。

将证书弄到系统目录,常见的有下面几种方式。如果不生效,试试重启设备哦。

2.1 Android Debug Bridge

简称ADB,做开发和测试的同学一般都了解。ADB的实现是C-S架构,电脑上的adb是客户端,手机系统上还跑了个守护进程adbd作为服务端,在电脑上用adb命令其实就是操控的adbd进程。如果希望将证书弄到系统目录,前提是让adbd获取root权限,并且能够解锁system目录。

# 申请以root模式运行adbd
# 成功的话会显示 restarting adbd as root
# 失败的话会显示 adbd cannot run as root in production builds
# 失败的话就放弃这种方案吧。
adb root

# 解锁system分区,注意不同设备系统命令可能有差别,具体需要咨询设备厂商
adb shell avbctl disable-verification
adb remount

# 将证书推送到系统证书目录
adb push reqable-ca.crt /system/etc/security/cacerts/364618e0.0

注意,Android 14还需要推送到/apex/com.android.conscrypt/cacerts

如果具有adb root权限,但是无法解锁system目录,怎么办?可以参考这篇文章临时挂载证书:91fans.com.cn/post/certif…

2.2 Magisk模块

前提是手机刷入Magisk环境,KernalSU也行。KernalSU据说需要额外给Root权限,具体我没测试过。

Reqable里面直接下载Magisk模块安装包,安装并启动即可,证书会自动复制到系统目录,并且支持Android 14。

截屏2024-07-10 15.05.32.png

2.3 拷贝文件

最后一种方式就是拷贝文件,也是最不推荐的一种方式。很多同学喜欢用这个方式,例如使用MT管理器拷贝文件,所以这里也简单说一说。

拷贝文件是可以的,但是请注意修改证书文件权限,一般需要手动赋予root权限 如果不清楚该给什么权限,请将拷贝的证书文件权限改成和其他系统内置证书文件权限一样即可。

3. 纠错排查

首先,需要明确一点,想在哪台设备上看流量,就需要安装哪台设备的根证书。很多用户不理解这个点,设备一多就非常容易装错了。

为了安全起见,Reqable默认会给每台设备都生成完全不同的根证书。如果你有同时使用电脑和手机的需求,建议在手机App初始化的时候选择协同模式并扫码连接电脑,这样可以保证手机和电脑证书是一致的,减少后面出错的可能性。

下面,列举一些用户常见的问题,供大家参考。

3.1 Reqable电脑和手机协同时,电脑上浏览显示SSL握手失败。

可能是手机安装的证书和电脑的根证书不同,按照前面所说,检查和对比证书的指纹值是否一致。

建议在手机初始化的时候,选择协同模式并扫码电脑二维码,这样Reqable会保证电脑和手机采用相同的证书,安装的时候就不会安装错了。

如果两个证书不一致,在Reqable手机上的设备连接页,点击右上角感叹号进行证书同步。证书同步完成后,再将手机证书安装到系统。

3.2 证书已经成功安装到系统目录,但是仍然显示SSL握手失败。

首先,用手机浏览器(建议firefox或者自带,不建议chrome)测试,看看访问reqable.com官网能否成功。如果手机浏览器也不行,可能是证书安装没成功,请参考前面证书安装的逻辑进行检查。如果浏览器可以,应用程序不行,可能存在下面这些情况:

  • 固定证书
  • 双向验证
  • 自定义CA Store
  • SSL版本不支持。
  • 证书本身异常。
3.3 什么是固定证书?

固定证书是指应用程序绑定了服务器的证书,Reqable重签的证书无法被信任。解决方案是将服务器的证书导入到Reqable中,Reqable将直接返回配置好的服务器证书。

解决方法:打开 证书 -> SSL证书,进入Reqable的服务端证书配置界面,导入服务器证书并配置相关的域名即可。

截屏2024-07-10 15.31.20.png

3.4 什么是双向验证?

正常情况下,SSL握手逻辑是服务器向客户端发送证书,客户端验证证书合法性。双向验证是在这个基础上,多了一步。客户端需要向服务器发送证书,服务器验证客户端证书的合法性。默认情况下,Reqable是不会向服务器发送证书的,所以这种情况会导致SSL握手失败。

解决方法:打开 证书 -> SSL证书,进入Reqable的客户端证书配置界面,导入客户端证书并配置相关的域名即可。

3.5 什么是自定义CA Store?

自定义CA Store指的是应用程序内置了常用的CA证书,不使用系统的CA证书。所以这种情况,将Reqable证书安装到系统对此应用程序是无效的。

解决方法:在编译应用程序前,将Reqable的证书追加到内置的CA证书中,这样应用程序在运行时就可以信任Reqable的证书了。

3.6 什么是SSL版本不支持?

Reqable理论上支持TLS 1.1、1.2和1.3,但是不排除应用程序使用了不兼容的版本。SSL也可能存在一些变种,例如国密SSL,这些Reqable目前是不支持的。另外,应用程序也可能使用了不兼容的加密算法,导致SSL握手失败,这些情况和证书都没什么关系。

3.7 什么是证书本身异常?

这里所说的证书不是Reqable的根证书,而是应用程序服务器返回的证书本身无法通过验证。常见的是证书的Common Name和访问域名不匹配。Reqable重签证书不会纠正证书本身存在的问题。

3.8 将证书安装到用户目录,并且配置了network_security_config.xml仍然SSL握手失败。

注意,网络安全配置文件一般仅对Android原生应用有效。如果你的应用是基于Flutter等框架,这种方案是无效的。建议将证书安装到系统证书目录。

3.9 证书安装到系统目录,Chrome内核浏览器提示NET:ERR_CERTIFICATE_TRANSPARENCY_REQUIRED错误

新版Chrome内核浏览器对系统目录证书启用了CT日志验证,即使证书已经成功安装到系统目录,仍然会出现NET:ERR_CERTIFICATE_TRANSPARENCY_REQUIRED到问题。遇到这种问题,请将证书从系统目录中移除并安装到用户目录。新版Chrome内核浏览器默认会信任用户证书并不会进行CT日志验证。

3.10 如果系统安装了多个Reqable证书会不会有影响?

理论上不会。但是,如果同一个证书既安装到了系统目录又安装到了用户目录,建议删除用户目录下的证书。

3.11 安装证书到用户目录后,系统提示网络可能会受到监控。

这是正常现象,但是Reqable在非用户主动操作的情况下不会拦截的网络流量。安装自定义证书本身就属于不安全行为,因此不建议在日常手机上安装证书。如果有临时测试的需求,测试完成后卸载证书即可。另外,如果你的设备安装了证书,请勿将证书导出提供给不信任的人。


感谢大家阅读,送一批Reqable礼品卡,点击这里兑换哦。

  • GT-4GWTV-9AEDW-4KZSM-U7W3P-JWRJS
  • GT-Z9HLN-WSMM9-ZJ4TJ-PCJEK-SGP46
  • GT-Q2CFH-SBTJB-ZVNHS-2K9F9-G5JZ8
  • GT-STV5E-2PHXA-344Q8-JS7RT-XCW92
  • GT-UHDK2-SQFTF-6QE83-NAVC8-X6KPV
  • GT-UVJAV-6UBNJ-7RN6F-Y4X2A-34UKX
  • GT-QUP5G-K8FNU-2TMTV-CN6GC-RWRN3
  • GT-6NXZJ-VL9L3-XVRQG-C2KCU-4BH2E