美文网首页
添加Fiddler/Mitmproxy证书为安卓系统证书

添加Fiddler/Mitmproxy证书为安卓系统证书

作者: jalen2024 | 来源:发表于2020-04-06 09:55 被阅读0次

    Android证书分为“用户证书”和“系统证书”两种,在设置->安全->"查看安全证书"列表中,可以看到“系统”和“用户”两个Tab。用户通过浏览器下载安装或者通过WLAN高级设置安装的证书均为用户证书。

    安装为系统证书有什么好处呢?

    (1)安装用户证书必须要设置开机密码,而且设置后就不能取消,除非先删掉所有的用户证书。如果安装为系统证书就不需要设置开机密码,自动化操作时更方便。

    (2)Android 7以上版本APP默认不信任用户证书,只信任系统证书,安装为用户证书,对APP的HTTPS抓包会失败。安装为全局证书才能被所有APP信任,方可进行HTTPS抓包。

    怎么将Fiddler或Mitmproxy的证书安装为安卓系统证书呢?

    Android的系统证书的存储位置是/system/etc/security/cacerts,证书文件必须是PEM格式,而且文件命名必须符合系统证书规范。

    下面是具体的步骤(注意:设备必须先ROOT):

    view plaincopy to clipboardprint?

    # 第一步,先下载好Fiddler或Mitmproxy的证书文件,PEM或者DER格式均可。  

    # 第二步,获取有效的系统证书文件名。  

    # 如果是PEM格式的:  

    openssl x509 -inform PEM -subject_hash_old -in mitmproxy-ca-cert.pem -noout  

    # 如果是DER格式的:  

    openssl x509 -inform der -subject_hash_old -in FiddlerRoot.cer  -noout  

    # 例如,输出8bbe0e8d  

    # 第三步,转换证书格式为PEM格式,并重命名证书为有效的系统证书名。  

    # 如果是PEM格式的:  

    openssl x509 -inform PEM -in mitmproxy-ca-cert.pem -out 8bbe0e8d.0  

    # 如果是DER格式的:  

    openssl x509 -inform der -in FiddlerRoot.cer -out 8bbe0e8d.0  

    # 第四步,上传准备好的证书文件到设备,例如  

    adb push8bbe0e8d.0 /sdcard/  

    # 第五步  

    # 以下进入adb shell后操作  

    adb shell  

    # 获取root权限  

    su  

    # 重新挂载系统,以可以写入文件到系统目录  

    mount -o rw,remount /system  

    # 复制证书到Android系统证书目录  

    cp /sdcard/8bbe0e8d.0 /system/etc/security/cacerts  

    # 修改证书权限  

    chmod644 /system/etc/security/cacerts/8bbe0e8d.0  

    # 上述可整合为一句  

    adb shell"su -c 'mount -o rw,remount /system;cp /sdcard/8bbe0e8d.0 /system/etc/security/cacerts;chmod 644 /system/etc/security/cacerts/8bbe0e8d.0;'"  

    # 重启设备  

    adb reboot  

    操作完成之后,我们就能在系统证书列表中看到,如下图所示:

    上述步骤很繁琐。下面给出一个我们APP数据采集项目中用到的自动化脚本,能够自动完成系统证书的安装全过程。支持PEM和DER两种格式。

    view plaincopy to clipboardprint?

    # coding: utf-8  

    # install_as_android_system_ca.py  

    # 添加证书为证书为安卓系统证书  

    # 要求:  

    # (1)本地OpenSSL版本 > 1.0;  

    # (2)目标设备已ROOT;  

    # 已测试验证:  

    # Android 5.1测试验证通过;  

    # Android 7.0测试验证通过;  

    # 注意:Android 6.0尚未验证通过,原因尚不知;  

    import sys  

    import os  

    import subprocess  

    def install(local_ca_path, device=None):  

    """安装证书为安卓系统证书

        local_ca_path - 证书的本地路径,支持CER格式和PEM格式;

        device - 目标设备序列号,若不指定则为默认设备;

        """  

    # 判断本地证书是否为PEM格式  

        with open(local_ca_path) as f:  

    if '--BEGIN CERTIFICATE--' in f.read():  

    # PEM格式的  

    is_pem =True  

    else:  

    # 非PEM格式的  

    is_pem =False  

    print 'CA file "{}" is {} format.'.format(local_ca_path, 'PEM' if is_pem else 'CER')  

    # 获取有效的系统证书文件名  

    print 'Generate valid android system CA file name for "{}"...'.format(local_ca_path)  

    if is_pem:  

    cmd ='openssl x509 -inform PEM -subject_hash_old -in {} -noout'.format(local_ca_path)  

    else:  

    cmd ='openssl x509 -inform der -subject_hash_old -in {}  -noout'.format(local_ca_path)  

    print cmd  

    android_system_ca_name = subprocess.check_output(cmd, shell=True).strip() + '.0'  

    print 'Android system CA file name for "{}" is: {}'.format(local_ca_path, android_system_ca_name)  

    # 准备传输到安卓系统的证书,本地路径  

    android_system_ca_filepath = os.path.join(os.path.dirname(sys.argv[0]), android_system_ca_name)  

    # 如果是CER格式,转为PEM格式  

    if local_ca_path.lower().endswith('.cer'):  

    print 'Convert CER "{}" into PEM "{}"...'.format(local_ca_path, android_system_ca_filepath)  

    if is_pem:  

    cmd ='openssl x509 -inform PEM -in {} -out {}'.format(local_ca_path, android_system_ca_filepath)  

    else:  

    cmd ='openssl x509 -inform der -in {} -out {}'.format(local_ca_path, android_system_ca_filepath)  

    print cmd  

    print subprocess.check_output(cmd, shell=True)  

    # 上传到SD卡根路径  

    adb_cmd_prefix ='adb ' if not device else 'adb -s "{}" '.format(device)  

    print 'Push "{}" onto device /sdcard/...'.format(android_system_ca_filepath)  

    cmd = adb_cmd_prefix +'push "{}" /sdcard/'.format(android_system_ca_filepath)  

    print cmd  

    print subprocess.check_output(cmd, shell=True)  

    # 将证书复制到系统证书目录下  

    print 'Move /sdcard/{} to /system/etc/security/cacerts, and set permission.'.format(android_system_ca_name)  

    cmd = adb_cmd_prefix +'''''shell "su -c 'mount -o rw,remount /system;cp /sdcard/{} /system/etc/security/cacerts;chown root:root /system/etc/security/cacerts/{};chmod 644 /system/etc/security/cacerts/{};'"'''.format(android_system_ca_name, android_system_ca_name, android_system_ca_name)  

    print cmd  

    print subprocess.check_output(cmd, shell=True)  

    # 把刚复制到安卓系统证书目录下的证书内容打印出来,看看是否复制成功了  

    cmd = adb_cmd_prefix +'shell cat /system/etc/security/cacerts/{}'.format(android_system_ca_name)  

    if '--BEGIN CERTIFICATE--' in subprocess.check_output(cmd, shell=True):  

    # 完成,提示重启设备  

    print 'Successed. Need to reboot the device now!'  

    else:  

    # 失败了,应该是权限不足,目标设备没ROOT  

    print 'Failed. Please root the device first!'  

    if __name__ == '__main__':  

    try:  

    local_ca_path = sys.argv[1]  

    except IndexError:  

    print 'Usage: python install_as_android_system_ca.py "Local ca path(support .cer and .pem)" [Device]'  

    try:  

    device = sys.argv[2]  

    except IndexError:  

    device =None  

        install(local_ca_path=local_ca_path, device=device)  

    相关文章

      网友评论

          本文标题:添加Fiddler/Mitmproxy证书为安卓系统证书

          本文链接:https://www.haomeiwen.com/subject/jphijctx.html