/ Android

Installing self-signed certificates on Android

One of the best trends these days is the shift to encrypted Internet traffic, aka Transport Layer Security or TLS, and mobile apps are not the exception, often when testing a mobile app we need/want to see the data being sent from and received on our mobile devices but since most of the apps are using TLS on their network requests we cannot just proxy the traffic and understand the communication between the app and its server.

Here is where the Man-in-the-Middle aka MitM approach comes handy. In order to see the traffic in plaintext we'll need our proxy to seat in the middle of the communication between the server and the app and to serve a valid TLS Certificate to the app.

I'll explain how to generate your own self-signed* TLS CA Certificate and install it on you Android device:

Generate a self-signed TLS CA Certificate

  • We'll use openssl to generate the key, in this case I'm using a key size of 3072 bits. Generate the key with the following command:
openssl genrsa -out burp.key 3072
  • Again, using openssl we'll generate the certificate, in this case I'm using a sha256 Hash and 3650 days (10 years) for its validity. Generate the certificate with the following command:
openssl req -x509 -new -nodes -key burp.key -sha256 -days 3650 -out burp.pem
  • For make it easier to import in your proxy (let's say Burp) we'll bundle the private key and the certificate:
openssl pkcs12 -inkey burp.key -in burp.pem -export -out burp.p12

Formatting the certificate

  • Get the hash of the certificate (something similar to ba4acff9) with the following command:
openssl x509 -inform PEM -subject_hash -in burp.pem | head -1
  • Make a copy of the burp.pem:
cp burp.pem burp-copy.pem
  • Rename it to the hash value with extension .0. It should be somethig like this ba4acff9.0

Installing the certificate on the Android device

  • Connect to your device and remount /system as read/write (by default Android mounts /system as read-only):
adb -s <device_id> shell
$ su
# mount -o rw,remount /system
  • Push the certificate to /system/etc/security/cacerts/ (you'll need root privileges):
adb root
adb -s <device_id> push ba4acff9.0 /system/etc/security/cacerts/

if you get an error either on adb root or adb push do the following:

  • Push the cert to the tmp folder (no root privileges needed for that):
adb -s <device_id> push ba4acff9.0 /data/local/tmp
  • Connect to your device and move the certo to /system/etc/security/cacerts/:
adb -s <device_id> shell
$ su
# mv /data/local/tmp/ba4acff9.0 /system/etc/security/cacerts/
  • Change the cert permissions and ownership:
$ chmod 644 /system/etc/security/cacerts/ba4acff9.0
$ chown root:root /system/etc/security/cacerts/ba4acff9.0

That's it! now your certificate is part of the trusted Root CA certificates. Note: You might need to go to Settigns -> Security -> Encryption and enable the certificate.

*self-signed means you'll generate the signing keys.

Photo by Adrien on Unsplash