android 14安装CA证书

前言

前两天给模拟器上安装CA证书,发现即使放入/system/etc/security/cacerts/,依然不能用Charles抓包,设置里查看,证书也没有生效,终于找到了一篇详细介绍原因的文章,记录一下,以后更好找。

准备证书

准备你的SSL证书,重命名。

1
2
3
openssl x509 -inform PEM -subject_hash_old -in charles_ssl.pem | head -1
#将证书命名为得到的的结果.0
adb push xxxxxx.0 /sdcard/

配置avd

首先你得是可写入的模拟器,所以运行以下shell,注意替换你的Device

1
2
3
emulator -avd Pixel_API_34 -writable-system
adb root
adb remount

将下列脚本保存成sh文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# Create a separate temp directory, to hold the current certificates
# Otherwise, when we add the mount we can't read the current certs anymore.
mkdir -p -m 700 /data/local/tmp/tmp-ca-copy

# Copy out the existing certificates
cp /apex/com.android.conscrypt/cacerts/* /data/local/tmp/tmp-ca-copy/

# Create the in-memory mount on top of the system certs folder
mount -t tmpfs tmpfs /system/etc/security/cacerts

# Copy the existing certs back into the tmpfs, so we keep trusting them
mv /data/local/tmp/tmp-ca-copy/* /system/etc/security/cacerts/

# Copy our new cert in, so we trust that too
mv $CERTIFICATE_PATH /system/etc/security/cacerts/

# Update the perms & selinux context labels
chown root:root /system/etc/security/cacerts/*
chmod 644 /system/etc/security/cacerts/*
chcon u:object_r:system_file:s0 /system/etc/security/cacerts/*

# Deal with the APEX overrides, which need injecting into each namespace:

# First we get the Zygote process(es), which launch each app
ZYGOTE_PID=$(pidof zygote || true)
ZYGOTE64_PID=$(pidof zygote64 || true)
# N.b. some devices appear to have both!

# Apps inherit the Zygote's mounts at startup, so we inject here to ensure
# all newly started apps will see these certs straight away:
for Z_PID in "$ZYGOTE_PID" "$ZYGOTE64_PID"; do
if [ -n "$Z_PID" ]; then
nsenter --mount=/proc/$Z_PID/ns/mnt -- \
/bin/mount --bind /system/etc/security/cacerts /apex/com.android.conscrypt/cacerts
fi
done

# Then we inject the mount into all already running apps, so they
# too see these CA certs immediately:

# Get the PID of every process whose parent is one of the Zygotes:
APP_PIDS=$(
echo "$ZYGOTE_PID $ZYGOTE64_PID" | \
xargs -n1 ps -o 'PID' -P | \
grep -v PID
)

# Inject into the mount namespace of each of those apps:
for PID in $APP_PIDS; do
nsenter --mount=/proc/$PID/ns/mnt -- \
/bin/mount --bind /system/etc/security/cacerts /apex/com.android.conscrypt/cacerts &
done
wait # Launched in parallel - wait for completion here

echo "System certificate injected"

将sh脚本推送到任意目录,然后配一个CERTIFICATE_PATH变量,然后执行sh

1
2
3
4
5
6

adb push install-ca.sh /data/local/
adb shell
export CERTIFICATE_PATH=/sdcard/xxxxxx.0
chmod +x /data/local/install-ca.sh
/data/local/install-ca.sh

参考

代码摘自这里