通过ADB安装用户证书

25
有没有一种通过ADB或其他"可脚本化"的方式,在"安全性 -> 受信凭证 -> 用户选项卡"下安装CA证书(.crt文件)的方法?

你解决了这个问题吗? - Incepter
唯一静默安装证书的方法是通过设备策略管理器,只有应用程序(.apks)可以注册为DPM,所以很遗憾,在长时间的研究后我走到了死胡同。@MohamedELAYADI - Nir Duan
我找到了一种方法来完成这个任务:openssl x509 -inform PEM -subject_hash_old -in charles-proxy-ssl-proxying-certificate.pem | head -1>totoset /p totoVar=<totoset totoVar=%totoVar%.0 && DEL totocat charles-proxy-ssl-proxying-certificate.pem > %totoVar%echo %totoVar%openssl x509 -inform PEM -text -in charles-proxy-ssl-proxying-certificate.pem -out nul >> %totoVar%adb shell mount -o rw,remount,rw /systemadb push %totoVar% /system/etc/security/cacerts/adb shell mount -o ro,remount,ro /systemadb reboot - Incepter
如果您对此感兴趣,可以在此处为Google问题点赞:https://issuetracker.google.com/issues/168169729?pli=1 - Tim Perry
7个回答

25

我找到了一种方法来完成这个操作,因此我能够信任 Charles Proxy 证书。它将被添加为受信任的 SSL 根证书。

首先,您需要获取证书哈希值。

openssl x509 -inform PEM -subject_hash_old -in charles-proxy-ssl-proxying-certificate.pem | head -1>hashedCertFile

我使用Windows,将其存储在一个变量中以自动化该过程。

set /p certHash=<hashedCertFile
    

set certHash=%certHash%.0 && DEL toto
cat charles-proxy-ssl-proxying-certificate.pem > %certHash%

openssl x509 -inform PEM -text -in charles-proxy-ssl-proxying-certificate.pem -out nul >> %certHash%

adb shell mount -o rw,remount,rw /system

adb push %certHash% /system/etc/security/cacerts/

adb shell mount -o ro,remount,ro /system

adb reboot

这是从这个答案复制的Unix版本:

PEM_FILE_NAME=logger-charles-cert.pem
hash=$(openssl x509 -inform PEM -subject_hash_old -in $PEM_FILE_NAME | head -1)
OUT_FILE_NAME="$hash.0"

cp $PEM_FILE_NAME $OUT_FILE_NAME
openssl x509 -inform PEM -text -in $PEM_FILE_NAME -out /dev/null >> $OUT_FILE_NAME

echo "Saved to $OUT_FILE_NAME"
adb shell mount -o rw,remount,rw /system
adb push $OUT_FILE_NAME /system/etc/security/cacerts/
adb shell mount -o ro,remount,ro /system
adb reboot

"adb shell mount -o rw,remount,rw /system" 不正确,应该使用 "adb shell mount -o rw,remount /system"。 - SelenUser
1
我还需要将证书的权限设置为644才能使其工作。否则,该证书将无法被识别。 - wddd
@Incepter,我没有看到证书安装在哪里?我看到PEM证书被推送到cacerts文件夹中。 - Ralf Wickum
2
adb shell mount -o rw,remount,rw /system -> mount: '/system' not in /proc/mounts - Dr.jacky

22
由于这篇回答 Install User Certificate Via ADB,我成功地修改了一个能够在 bash shell 上运行的脚本。
PEM_FILE_NAME=logger-charles-cert.pem
hash=$(openssl x509 -inform PEM -subject_hash_old -in $PEM_FILE_NAME | head -1)
OUT_FILE_NAME="$hash.0"

cp $PEM_FILE_NAME $OUT_FILE_NAME
openssl x509 -inform PEM -text -in $PEM_FILE_NAME -out /dev/null >> $OUT_FILE_NAME

echo "Saved to $OUT_FILE_NAME"
adb shell mount -o rw,remount,rw /system
adb push $OUT_FILE_NAME /system/etc/security/cacerts/
adb shell mount -o ro,remount,ro /system
adb reboot

(是的,我知道这可能应该是一条评论,但我还没有足够的声望将其发布为评论)


1
我收到了这个错误。./ssl_pinning.sh: 第3行:!!:找不到命令 head: cert_name=.0: 没有那个文件或目录 - Gorio
@Gorio,你可能会发现这个脚本很有帮助。你肯定需要稍微更新一下它(我无法将结果文件复制到AVD的/system分区,但在Genymotion上成功了)。 - Sufian
你的重新挂载命令中有太多的 rorw - BLuFeNiX

11

我按照以下步骤成功地将服务器证书显示在信任的凭据->用户选项卡下(而不是其他答案所展示的系统选项卡下):

#!/bin/bash
subjectHash=`openssl x509 -inform PEM -subject_hash_old -in server.crt | head -n 1`
openssl x509 -in server.crt -inform PEM -outform DER -out $subjectHash.0
adb root
adb push ./$subjectHash.0 /data/misc/user/0/cacerts-added/$subjectHash.0
adb shell "su 0 chmod 644 /data/misc/user/0/cacerts-added/$subjectHash.0"
adb reboot

在Lineage OS Android 10上测试过,运行得很好。请勿忘记在重启后单击“受信任凭据->用户”中的“信任”按钮。 - Hannes Tiltmann

7

将文件推送到设备上

adb push "C:\path\cacert.cer" "/data/local"

启动 CertInstaller

adb shell am start -n com.android.certinstaller/.CertInstallerMain -a android.intent.action.VIEW -t application/x-x509-ca-cert -d file:///data/local/cacert.cer

现在,请按照您设备上将出现的提示完成安装。

2
我在我的Wear OS手表(Fossil Gen 6)上尝试了这个。adb没有权限上传到“/data/local/”,但可以上传到“/data/local/tmp/”。以下是可能的MIME类型:
  • application/x-x509-ca-cert
  • application/x-x509-user-cert
  • application/x-x509-server-cert
  • application/x-pem-file
  • application/pkix-cert
  • application/x-pkcs12
  • application/x-wifi-config
- Fulkerson
与@Fulkerson相同。在安装证书之前,我的强制设置屏幕锁定。有没有办法不设置屏幕锁定? - Dr.jacky
@Fulkerson 你成功在手表上安装证书了吗?运行命令时,我在手表上看到了用户界面,但是在点击“确定”后出现了一个错误提示。当使用ADB连接时,异常信息是:W CertInstaller: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.android.settings/com.android.settings.security.CredentialStorage}; have you declared this activity in your AndroidManifest.xml? - virtualdj

5

2022年:httptoolkit提供了一种很好的解决方案,可以在已经root的设备/模拟器中无需重启即可注入自定义证书。

详情请参见:https://httptoolkit.tech/blog/intercepting-android-https/#injecting-ca-certificates-into-rooted-devices

    set -e # Fail on error
    # Create a separate temp directory, to hold the current certificates
    # Without this, when we add the mount we can't read the current certs anymore.

    mkdir -m 700 /data/local/tmp/htk-ca-copy
    # Copy out the existing certificates

    cp /system/etc/security/cacerts/* /data/local/tmp/htk-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 mount, so we keep trusting them

    mv /data/local/tmp/htk-ca-copy/* /system/etc/security/cacerts/
    # Copy our new cert in, so we trust that too

    mv ${certificatePath} /system/etc/security/cacerts/
    # Update the perms & selinux context labels, so everything is as readable as before

    chown root:root /system/etc/security/cacerts/*
    chmod 644 /system/etc/security/cacerts/*
    chcon u:object_r:system_file:s0 /system/etc/security/cacerts/*
    # Delete the temp cert directory & this script itself

    rm -r /data/local/tmp/htk-ca-copy
    rm ${injectionScriptPath}
    echo "System cert successfully injected"

源代码


1

这只是在非Root Android上启动“您是否要信任此证书窗口”的解决方案。这是@hoghart45提供的答案,但它还有一行代码,确保您有权限将证书粘贴到/data/local/..目录中:

certificateName=ca.crt
ca_dir_in_phone="/data/local/tmp/try3"
ca_path_in_phone="$ca_dir_in_phone/$certificateName"

adb shell mkdir -m 700 "$ca_dir_in_phone"
adb push "$certificateName" "$ca_path_in_phone"

adb shell am start -n com.android.certinstaller/.CertInstallerMain -a android.intent.action.VIEW -t application/x-x509-ca-cert -d file://"$ca_path_in_phone"

enter image description here

为了完整起见,这里是一个正在进行中的Python项目WIP,它还使用uiautomator以受控方式自动点击“确定”按钮。(它在点击之前验证它是否是确定按钮,而不仅仅是发送盲目的输入,如send keyevent 20命令)。免责声明,我参与了该项目。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接