安装Android自定义证书

0x00 背景

工作上经常需要要mitm Android的通信(就是用burp什么的),需要在安卓上安装burp的证书。但是你会发现安卓7.0之后有了network-security-config这个选项,可以让app只信任系统证书,这样的话即使你安装了用户证书也无法进行mitm。

0x01 解决方案

所以我们需要把我们自己的root CA证书安装成系统证书(需要root),这个方法在很多网站上可以看到,简单整理一下就是:

  1. 计算证书哈希值:
    openssl x509 -noout -subject_hash_old -in cert.pem
    

    假设结果是80326040,则我们把证书重命名为80326040.0。

  2. 把/system mount成为可读可写。

    mount -o remount,rw /system
    
  3. 把80326040.0拷贝到Android的路径/system/etc/security/cacerts/下,并添加读权限:
    chmod 644 80326040.0
    

0x02 进阶

可是你会发现,在Android 7以上,即使你把burp的自定义证书添加进系统证书里,这个证书也是不工作的。原因是chrome从2018年开始只信任有效期少于27个月的证书:https://www.entrustdatacard.com/blog/2018/february/chrome-requires-ct-after-april-2018,而我们的burp发行的root证书有效期是2014年到2038年,当burp使用这个根证书发行各个网站的证书的时候,也会把有效期限设置为2014到2038,导致chrome判定这个证书无效。所以解决的办法是我们自己做一个两年的root证书导入burp。下面来介绍如何生成root CA证书:

  1. 生成密钥
    openssl genrsa -out key.pem 3072 -nodes
    
  2. 下载这个openssl.cnf并使用如下命令生成证书:
    openssl req -new -x509 -key key.pem -sha256 -config openssl.cnf -out cert.pem -days 730 -subj "/C=JP/ST=/L=/O=nevermoe/CN=MiTM CA"
    
  3. 把密钥和证书导出成pfx格式
    openssl pkcs12 -export -inkey key.pem -in cert.pem -out cert_and_key.pfx
    
  4. 把cert_and_key.pfx导入burp

  5. 按照0x01中的方法把根证书cert.pem保存到安卓里。

0x03 一些坑

为什么没有人发现这个问题,这是因为如果你直接在安卓里选择从sd卡安装burp的证书,burp的根证书会出现在用户证书而不是系统证书里,对于用户导入的证书,chrome似乎不会对用户导入的根证书发型的证书的有效期进行检查。所以一般情况下如果直接把burp的根证书导入到android的用户证书里是不容易发现什么问题的。
另一个要注意的点是,我们发行的root证书一定要有x509v3 extesion,其中包含了CA: True这个属性,不然我们生成的根证书是无法以导入成用户信任的根证书的。

0x04 一些有用的命令

# 阅读证书内容
openssl x509 -in cert.pem -text -noout
# 转换证书格式 der -> pem
openssl x509 -inform der -in certificate.der -out certificate.pem
#  转换证书格式 pem -> der
openssl x509 -outform der -in certificate.pem -out certificate.der

如果输入的证书是der格式的话,加上 -inform der 即可。