Installing root certificate in android and mitmproxy

Well, since you are here, you are probably planning to spy on traffic generated by the apps on your phone, probably looking to find out what apps are leaking your private information !

How this all works: When an application on your phone contacts a website/web-server over a secure connection, your phone checks the certificate, and checks whether or not that certificate was issued by an authority the phone trusts, what we are doing is telling the phone to add YOU to the list of trusted authorities, then, we create a proxy that the phone connects through (mitmproxy). Now, the proxy contacts the website on behalf of the application that sent the request, gets the response / contents of that page, saves a copy of that response, and repackages it using our own security certificate, then sends it to the phone, at this stage, the phone thinks the certificate belongs to the website it was contacting (Because now it trusts you), and everything works as it normally would. This does not work if the app has a pinned certificate, a pinned certificate is when an app does not trust the list of authorities the system maintains and requires a certain certificate, but this too has a workaround !

here is what you need to do.

I am assuming you already have a rooted virtual android device (AVD), if not, here are the instructions, in my case, even though it is mid 2026, i decided to go with a Google Pixel 6 with android 12 (The pixel six has updates up to the most current Android 17, but i decided to go with Android 12)

You need to create a root certificate, and install it in both mitmproxy and android, the mitmproxy gets the pem file with the certificate and private key (So that it can create certificates for websites on the fly), while android gets the one with the certificate (Obviously)

1- Gnerate the private key

openssl genrsa -out android-mitm-ca.key 4096

2 – Create the CA certificate


openssl req -x509 -new -sha256 -key android-mitm-ca.key -out android-mitm-ca.crt -days 3650 -subj "/C=JO/O=Android Traffic Analysis/CN=Android MITM Analysis CA" -addext "basicConstraints=critical,CA:TRUE" -addext "keyUsage=critical,keyCertSign,cRLSign"

3- Installing mitmproxy (On your debian machine)

install Prerequisites:

sudo apt install python3-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg-dev zlib1g-dev

Debian 13 does not have it in repositories (12, and 14 do !), so we need to install from binaries downloaded from the website ! so i put them in /opt/mitmproxy and symlinked the files in /usr/local/bin

4- Concatinate/combine key and cert into 1 file for the mitmproxy

cat android-mitm-ca.key android-mitm-ca.crt > ~/.mitmproxy/mitmproxy-ca-my.pem
chmod 600 ~/.mitmproxy/mitmproxy-ca-my.pem

5- running and check that mitmproxy is using our cert

First, run mitmproxy.

NO-GO: mitmproxy –listen-host 192.168.7.119 –listen-port 8080 –certs “*=$HOME/.mitmproxy/mitmproxy-ca-my.pem” (No go because certs is for individual domains)

NO-GO:

mitmproxy --certs "*=$HOME/.mitmproxy/mitmproxy-ca-my.pem"

Or if needed

mitmproxy --listen-host 192.168.7.119 --listen-port 8080 --set confdir="$HOME/.mitmproxy-my"

Or if you want access from outside your network

mitmproxy --listen-host 192.168.7.129 --listen-port 8080 --set block_global=false --set confdir="$HOME/.mitmproxy-my"

From another terminal, let us try to get the contents of example.com through the proxy:

openssl s_client -proxy 192.168.7.119:8080 -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -issuer -subject

Now, if the proxy works as intended, and is correctly signing our requests with our own certificate, we should see something like isuer: Android MITM Analysis CA (The name we chose)

So, now our proxy is ready and serving, all that remains is relevant to Android, we have already made the android certificate to add (OUR_HASH.0)

Installing the certificate on the android phone

The only thing that is confusing about this section is that not all android phones work in the same way ! I am deliberately using Android 12 (Will install most software while being somewhat easier to tinker with), you on the other hand may be using android 16 or 17 (The latest at the time of writing).

Also, I am using a virtual android phone (With Android Studio), you may be using an actual rooter physical phone !

So, I will outline when something is going to be different on other android versions, and you will have to figure it out (Use Google, or gemini or something)

6- Certificate File Name for android

figure out the hash for the filename of the Android file (The file name should be “hash.0”, replace hash with the actual hash resulting from the below) this is how android expects the file name to be

HASH=$(openssl x509 -inform PEM -subject_hash_old -in android-mitm-ca.crt | head -1)
echo "$HASH"

Now, copy the file android-mitm-ca.crt and name the copy the same as the resulting hash with an added .0 at the end (THEHASH.0)

7- If android 16+ (I am using 12, but if you have 16+)

If your rootAVD image is Android 16 or above, don’t blindly follow the old /system/etc/security/cacerts/ procedure. Android 16 changed the system certificate location, and current mitmproxy documentation has a separate procedure involving a Magisk certificate-moving module.

check your android version

adb shell getprop ro.build.version.release
adb shell getprop ro.build.version.sdk
adb shell getprop ro.product.cpu.abi
adb shell su -c 'id'
$ adb shell getprop ro.build.version.release
12
$ adb shell getprop ro.build.version.sdk
31
$ adb shell getprop ro.product.cpu.abi
x86_64
$ adb shell su -c ‘id’
uid=0(root) gid=0(root) groups=0(root) context=u:r:magisk:s0

So, in my case, I am running android 12 ! Software development kit 31 (API level), X86 cpu, and (context=u:r:magisk:s0)

8- Explore the filesystem

Let us check and explore the files and folders on filesystem


> adb shell su -c 'ls -ld /system/etc/security/cacerts'
drwxr-xr-x 2 root root 4096 2023-07-26 23:02 /system/etc/security/cacerts

> adb shell su -c 'mount | grep -E " /system | / "'
/dev/block/dm-4 on / type ext4 (ro,seclabel,relatime)

> adb shell su -c 'ls -l /system/etc/security/cacerts | head'
total 952
-rw-r--r-- 1 root root 2871 2023-07-26 23:02 01419da9.0
-rw-r--r-- 1 root root 2914 2023-07-26 23:02 04f60c28.0
-rw-r--r-- 1 root root 2345 2023-07-26 23:02 0d69c7e1.0
-rw-r--r-- 1 root root 4622 2023-07-26 23:02 10531352.0
-rw-r--r-- 1 root root 4724 2023-07-26 23:02 111e6273.0
-rw-r--r-- 1 root root 4308 2023-07-26 23:02 12d55845.0
-rw-r--r-- 1 root root 2599 2023-07-26 23:02 1ae85e5e.0
-rw-r--r-- 1 root root 4931 2023-07-26 23:02 1df5a75f.0
-rw-r--r-- 1 root root 4535 2023-07-26 23:02 1e1eab7c.0

So, we do have the path /system/etc/security/cacerts on the phone, system (See second command above) is mounted read only, there are 952 certificate files in the /system/etc/security/cacerts folder.

Reminder: On Android 12, the traditional system CA location we’re interested in is: /system/etc/security/cacerts/ , The certificates are stored there using the OpenSSL subject-hash filename convention, e.g.: xxxxxxxx.0

The plan at this stage is to use magisk to add our certificate as an overlay, this way, we don’t need to modify the actual system, meaning, we will not be mounting system in read-write mode, read-only is fine by us

9- Explore Magisk

So let us start by checking what version of MAGISK is installed on the phone, and where it lives

> adb shell su -c 'magisk -v'
26.4:MAGISK:R
> adb shell su -c 'magisk --path'
/debug_ramdisk
> adb shell su -c 'ls -la /data/adb/modules'
total 24
drwxr-xr-x 3 root root 4096 2026-08-26 12:05 .
drwx------ 6 root root 4096 2026-08-26 12:11 ..
drwxr-xr-x 3 root root 4096 2026-08-26 12:07 hosts

Since this is rootAVD/Magisk, the clean approach is to use a Magisk overlay so we don’t modify the underlying system image.

10- Create the Magisk module with the certificate in it !

we can create our own small Magisk module specifically for the CA without touching the original system image. (the only existing module is hosts)

To create a magisk module we need to do the following

10.1- Create an identical folder structure on my debian machine *(Yours can be windows)

mkdir -p ~/.mitmproxy/module/system/etc/security/cacerts

Move your certificate (xxxxx.0) to the cacerts folder we created above

Now create the module file (Module dfinition file), obviously you can create it with a text editor as well if you wish.

cat > ~/.mitmproxy/module/module.prop <<'EOF'
id=android-mitm-ca
name=Android MITM Analysis CA
version=1.0
versionCode=1
author=Voodoo
description=Custom CA certificate for controlled Android traffic analysis
EOF

Now, put the contents of the module directory (Without the module directory itself) in a zip file

cd ~/.mitmproxy/module
zip -r ../android-mitm-ca.zip .

Now, open the zip file in fileroller (or 7-zip or winrar, whatever suits you) and make sure we have

module.prop
system/
system/etc/
system/etc/security/
system/etc/security/cacerts/
system/etc/security/cacerts/XXXXXXXX.0

If all looks good, super, we have the zip file for android…. go ahead and push it to the android virtual machine

> adb push ~/.mitmproxy/android-mitm-ca.zip /data/local/tmp/

Now, when the above works, install the zip file with magisk

> adb shell su -c 'magisk --install-module /data/local/tmp/android-mitm-ca.zip'
- Device is system-as-root
**************************
Android MITM Analysis CA
by Voodoo
**************************
*******************
Powered by Magisk
*******************
- Extracting module files
- Done

If you get an error above DO NOT REBOOT, only reboot if you get a message like the one i got. if not, Sorry man, you need to reverse the steps above ! something with the rootAVD restore command should do

Now, after rebooting (adb shell reboot), run this to see if our certificate appears !

adb shell su -c 'ls -l /system/etc/security/cacerts/'

Looks fine to me, but let us double check (replace the xxx with your actual file name)

adb shell su -c “ls -l /system/etc/security/cacerts/xxxxxx.0”
-rw-r–r– 1 root root 2000 2026-08-27 20:28 /system/etc/security/cacerts/xxxx.0

And if everything was done correctly, “adb shell su -c ‘mount | grep ” / “‘” should still show read-only

Now, let us play, I am very skeptical that this would work (Unless your android has openssl), but it can’t hurt to try… anyway, failiure here means nothing is the error is that “openssl: inaccessible or not found”, it is expected, and means nothing

adb shell su -c "openssl x509 -in /system/etc/security/cacerts/fea8a918.0 -noout -subject -issuer"

Pinned certificates

there are ways to get around this, ways from things as simple as using apk-mitm to remove the pinning, all the way to more serious stuff such as using jadx to modify the software before playing this game.

Here are some tools that can come in handy for this

  • FRIDA: Lets you inject snippets of JavaScript or your own library into native apps + simple tools built on top of the Frida API.
  • APK-MITM: (https://github.com/shroudedcode/apk-mitm): Remove certificate pinning from APK files
  • objection is a runtime mobile exploration toolkit powered by Frida, which supports certificate pinning bypasses on iOS and Android.
  • ssl-kill-switch2 blackbox tool to disable certificate pinning within iOS and macOS applications.
  • android-unpinner : From the same people who make the MITMPROXY, it modifies Android APKs to inject Frida and HTTP Toolkit’s unpinning scripts.

apk-mitm

node --version
npm --version
sudo apt install zip unzip
npm install -g apk-mitm

Now, to remove the pinning in your app

apk-mitm <path-to-apk>

Installing and rooting an AVD

Here, I would like to install an AVD with Android Studio, then root it

Where to install

First of all, I would like to have my virtual machines installed on a different SSD (Or Hard drive), in my case, this is because my main disk is always busy, and i want the Android Virtual Device to be snappy, others may have storage space concerns, others may want to skip this step, depends…

To do this on my Debian machine, i need to add the following line to ~/.bashrc

export ANDROID_AVD_HOME="/hds/ssngoem/avd"

On windows, i would have to Edit the system environment variables.

If you just want to move a machine, move it from ~/.android/avd/, don’t move the ini file, instead edit the ini file and fix the location of the virtual machine to wherever you put it

Make it

Now, all we need to do is create a machine in Android Studio!

Root it

To root the phone we need rootAVD

Start by checking whether the AVD is connected to the PC with adb devices

adb devices
List of devices attached
emulator-5554 device

So it seems that it is !

Now, we need rootAVD from newbit (https://gitlab.com/newbit/rootAVD)

git clone https://gitlab.com/newbit/rootAVD.git
cd rootAVD
./rootAVD.sh listAllAvds (On windows, use rootAVD.bat instead of sh)

The above command will give you a list of commands for each and every one of your Android Virtual Devices ! I will copy the first one, but the end of every line there is the last word that explains what it is

Once you run the command to root the phone, the phone will reboot (Or shutdown), you need to start the phone again (Make sure you chose cold boot from the … menu), and you will find a tool called magisk on the phone emulator, you need to run it, when you run it for the first time, it will tell you there is additional setup that needs to be done, which will reboot the device again

Your phone should now be rooted, to be sure, you can

adb shell
whoami
su (The phone screen will ask for permission)
whoami

Remotely controlling the S10+

I have been using a google pixel 6 pro for some time now, excellent phone, and it already got the android 16 update, so thanks to google for extending our support ! rumor has it that with this extended support, we will also get android 17 !

Now, my old Samsung S10+ that I had before the pixel 6 has a broken screen, the upper side of the screen works, but the touch is broken, the lower 30% of the screen are black but the touch screen works, it sustained this injury when a bottle of vodka went crashing down on the screen when the phone was fairly new ! the poor thing never stood a chance, and was only used for a few months (if even that)

Anyway, to avoid keeping my phone occupied when I am taking a video, I have been using a xiaomi note 4, not bad a camera, but the S10+ is obviously a better option for this task

So, how can I use it, turns out there is open source software called scrcpy that should be able to do both jobs, mirror the screen on a PC or another phone, and send the input to the phone ! scrcpy should be able to connect to the PC through WIFI (If your phone is recent enough) or USB (Whatever is ADB compatible)

Installing scrcpy on my PC

NOTE: I use Gnome on a Linux Debian machine, but installing it on windows should be straight forward !

sudo apt install scrcpy adb -y

This installs both Scrcpy and Android Debug Bridge (ADB), which are needed to communicate with your phone.

NOTE: The above does not work in bookworm as there is no such package (Both previous and next versions do have it), so instead, if you are on bookworm, follow the steps below

Bookworm installation

sudo apt install git ffmpeg libsdl2-dev adb gcc make meson ninja-build pkg-config libavcodec-dev libavformat-dev libavutil-dev libusb-1.0-0-dev libavdevice-dev adb

sudo apt install openjdk-17-jdk gradle

Now, we need the SDK !
mkdir -p ~/Android && cd ~/Android
wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
unzip commandlinetools-linux-*.zip -d cmdline-tools
cd cmdline-tools
mv cmdline-tools latest
NOTE: You will have the folder cmdline-tools inside the folder cmdline-tools so we renamed the inner to latest

vi ~/.bashrc
export ANDROID_HOME=$HOME/Android
export PATH=$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH

source ~/.bashrc

Now, you need to accept all the license agreements

~/Android/cmdline-tools/latest/bin/sdkmanager --licenses

cd ~
mkdir src
cd ~/src

git clone https://github.com/Genymobile/scrcpy

cd scrcpy

meson setup build
ninja -C build
sudo ninja -C build install

Now, I assume you know how to connect your phone to your PC via ADB, if not, there are tutorials all over the internet (Here is an example)… You start by enabling developer tools mode on the phone by tapping the build number 7 times then enable debug (Either USB or WIFI or both)

Once that is done, you can get a clone of the screen with the following

adb devices

scrcpy -s device1_serial

You don’t need the -s serial part if there is only 1 device

Also, you can run multiple instances

Update

Now that i have upgraded my Debian version, it no longer works, the reason is simple, when i was on bookworm, it was compiled for ffmpeg 5, now i am on trexie (13) and the included ffmpeg is 7 (.so.61)…

What needs to be done is to recompile !

git clone https://github.com/Genymobile/scrcpy.git
cd scrcpy
meson setup build
ninja -C build
sudo ninja -C build install


Verify
ldd /usr/local/bin/scrcpy | grep avformat

scrcpy --version

Mobile Development

This is just a summary of the tools you may or may not use for mobile development

Cross Platform

  • Dart-Flutter
  • React Native
  • Kotlin Multiplatform (& compose-multiplatform ;))
  • Ionic
  • .NET MAUI, (Successor to Xamarin.Forms), develop in C#
  • NativeScript: Build mobile apps with Angular, Vue.js, etc !

Android

  • Android Studio
    Kotlin / Java
  • Jetpack Compose : composable functions – define your app’s UI programmatically

iOS

  • Xcode

My flutter notes

This is an unstable post, I add comments here, then move them to their final destination on a separate post, posts are listed on the Dart/Flutter page, so it is completely normal for this post to be empty most of the time !

The reason I am interested in flutter is that it may just be the best option to accompany my RUST programs and fit them with relatively efficient front ends ! again, potentially the best fit FOR ME AND MY RUST PROJECT IDEAS

LineageOS for my J500H phone

This phone is so old and low on storage space, that if it is left to connect to the internet, the storage fills up completely before you get the chance to disable updates !

I have moved to external storage before, but as you might expect, this would have been a great solution if i had slightly more space on the device itself (Original post here)

For development purposes, I would like this phone to have as low an android version as possible, and the lowest android version of LiniageOS itself is 6 (Marshmallow)

CyanogenMod, the name of LiniageOS before Nougat, but it overlaps with LiniageOS at Android version 6, although Android 5 on the phone would have been more useful for my development endeavors, I decided to go with Android 6 anyways. Which happens to be LiniageOS 13.

The best file managers for Android

There is no shortage of file managers for android, both free and paid

The popular Paid file managers are

  • MiXplorer = Paid, no trial, plugins to add functionality
  • Solid Explorer = 14 Day trial, during trial, you get ads (Root explorer, archiver, Chromecast, File categorization) + Local + FTP, LAN, sFTP, WebDav, NextCloud, etc…..
  • File Commander = 7 Day Trial, during trial there are ads, FTP, LAN, cloud providers, etc…

Free and open source

  • Material Files = Simple file manager, but well done in terms of design and good android development practices, Open source mostly written in kotlin (Github =>)
  • Amaze File Manager = Simple material design file manager, written in both Java and Kotlin (Github =>)
  • NextCloud Android client = Works with the self hosted Next Cloud (But so do unofficial managers) (Github =>)

Free but not open source

  • File Manager by Xiaomi = Has network options (LAN, FTP)
  • Google Files = Basic, supports Google Drive and OneDrive, google drive launches the drive app

2.5MM audio jacks

2 pin connector TS (tip, sleeve)
3 pin connectors, TRS (tip, ring, sleeve)
4 pin connectors, TRRS (tip, ring, ring, sleeve)

TRRS

Two standards exist for TRRS (4 Pin)

CTIA, which you can think of as apple, and i will call it apple throughout the post to help you focus on what matters, and OMTP, Which is everything else which i will call Android from here on.

For android (And almost any non apple device), the sleeve (Pin closest to the wire) is the ground, and the ring right above it would be the microphone… the other ring and the tip are the two speakers, right and left, In apple’s setup, the ground and microphone are switched together !

TRS

In a 3 pin connector (TRS), When it is meant to carry microphone signal, the tip is the microphone signal, the sleeve is still the ground, and the ring may carry any other signal such as a single speaker channel.

Music players for android

When it comes to MP3 players, there is definitely no shortage, but finding a good one is a task

Here are the most popular one, each with it’s advantages and disadvantages

Retro Music Player

Open source: github
Available on google play and F-Droid
Elegant, plays music files and does not do much more
Appears to be written in Kotlin

Fossify Music Player

Open Source: Github
Available on Google Play and F-Droid
Elegant, plays music files and does not do much more
Appears to be written in Kotlin

Wireless android studio

I run windows in KVM, and the QEMU android Emulator that ships with Android studio crashes all the time, so the obvious solution, with all those android devices I have is to connect a phone to android studio, It is faster and spares me the hassle of finding out why nested virtualization is so terrible

But having a phone connected via USB is not optimal, as i have to pick it up every time i want to run my under development software on it !

The answer seems to be in the

1- install Android WiFi ADB : A plugin easy to install in Android studio

2- A phone with Android 11 and above

So let us do this step by step

  1. Download SDK platform-tools and install it (Copy it somewhere and add that to your system path)
  2. Enable developer options on the phone (Keep tapping build number)
  3. From developer options, Enable wireless debugging
  4. Select Pair device with pairing code. Take note of the pairing code, IP address, and port number displayed on the device (see the above image).
  5. Open the command prompt and run the command adb pair ipaddr:port
    adb pair 192.168.7.101:45353
    Enter pairing code: xxxxxx
    daemon not running; starting now at tcp:5037
    daemon started successfully
    Successfully paired to 192.168.7.101:45353 [guid=adb-RF8M4xxxxxxx-xxxxxxx]
  6. Now, to have it appear as a device in android studio… Go to wireless debugging and notice the port number, then using that IP and port, use the following command
    adb connect 192.168.7.101:35127
  7. Recommended: Install the “Android WiFI ADB” plugin in android studio

Note: The Pairing port is not the same as the connection port ! so pay attention to that