Adding SSL root certificates to Android Ice Cream Sandwich, Jellybean and KitKat

android-logo-whiteThe goal is to add the CACert root certificates to my Android phone running Ice Cream sandwich. I use CACert certificates on my personal host for everything like IMAP4, SMTP submission, CalDAV and CardDAV. We will use Cacert as an example, but the same method could be applied to any root certificate.

In previous Android versions, the SSL certificates were stored in a Bouncycastle container. The CaCert wiki has a step-by-step guide on how to add certificates for those versions.  With Ice Cream Sandwich onwards, Android uses the openssl libraries and stores SSL certificates in more familiar way. All included root certificates are placed in the “/etc/security/cacerts/” directory.
If you want to add others, the kosher way is to add them to the personal keystore through the phone GUI, which makes no difference between personal certificates and root certificates. Consequently, Android expects you to set a password or PIN code on the keystore, which can be quite annoying and actually a stupid design from Google in the case of root certificates.

I followed the following path to install the CACert root certificate. There are at least two ways to reach the same goal. It can be done using the “adb” tool from the Android SDK. I chose to use tools most users will understand.

Prerequisite: a rooted phone. How to root your phone is beyond the scope of this post. It can vary quite much according to manufacturers and models. Google is your friend.

Step 1: Get the certificate(s) you want included. They should be in PEM format. For CaCert, it is here.

Step 2: Openssl uses a hash key to find the certificate. The original certificate should be renamed according to that hash key. The Openssl binary can generate this name.  If you use a *nix-based operating system, openssl is part of the standard installation. On MS-Windows, there is a port. Notice that Android uses the 0.9x series of openssl. Most up to date *nix versions (and the windows port) use the 1.0x version. This matters because the hash keys generated are different. To generate the hash, use:

  • for the 0.9x openssl: openssl x509 -noout -subject_hash  -in your-root-cert
  • for the 1.0x openssl: openssl x509 -noout -subject_hash_old  -in your-root-cert

Step 3:  The above command will display the hash value. Rename the certificate to its hashed name: mv your-root-cert.pem hashed_name.0  (e.g “mv root.crt 5ed36f99.0” for the CACert root)
Update 27 Nov 2013: it seems some implementations cannot use the plain certificate as published on the CaCert web site. Some information needs to be appended to it. Sebastiaan, in a comment below pointing to his blog, suggests using:

cat root.crt > 5ed36f99.0
openssl x509 -inform PEM -text -in root.crt -out /dev/null >> 5ed36f99.0

Step 4: Copy the file to your phone SD Card.  You should know how to do that

Step 5: Launch a terminal emulator window on your phone (I used this one) and run the following commands. replace “5ed36f99.0” with the actual name of your certificate :

cp /mnt/sdcard/5ed36f99.0 /etc/security/cacerts/
chown root.root /etc/security/cacerts/5ed36f99.0
chmod 644 /etc/security/cacerts/5ed36f99.0
ls -l /etc/security/cacerts/5ed36f99.0

All done ! Go ahead and test it. You may need to reboot your phone for this work.

Usual disclaimer: the above might brick your phone, but should be without danger to your health.

  1. Richard Seepaul

    I have used Sebastian Giebels method in the past to add CA files to /system/ it worked using Terminal CLI or using an App like Root Explorer.
    A few versions of android ago it stopped working.
    It currently does not work for Android 6.0.1 Build MOB30l. It is as if you are NOT really root or the /system/etc/security/cacerts folder is on a ROM chip or CD-ROM.
    Looks like google is up to their normal tricks.
    If someone knows which previous build still supports adding .0 format files to the cacerts folder please let us know.

    • Richard Seepaul

      Looks like uncle google started bundling more “system” software into the last few versions.
      If you uninstall things like Hindi and Korean keyboard input or any other google system bloatware then suddenly you are able to add certs to your Trusted Root store aka cacerts folder.

  2. @Sebastiaan /etc is a sym-link to /system/etc so they’re the same thing.

  3. After trying a lot of ways to import the two CAcert certificates into the android system certificate store of my tablet, I found your blog, and with a few corrections I managed to get CAcert working without needing a lockscreen pin/password

    I’ve detailed my steps on my blog (click my name above this post to visit it).

    One of the differences between my method and yours is that i’m using /system/etc/security/cacerts/
    instead of /etc/security/cacerts/, I included the Class 3 certificate and I explained how to mount the /system partition read-write.

    Thank you for your research!

  4. Thanks a lot! After spending over an hour in google i’ve found this article. This method is useful just because standart android certificate importer forces user to use pinlock.

  5. Is the hash in your post missing a f? Here the hash of root.crt is 5ed36f99.

    But another more important question (as it seems that the filename does not really matter):
    How did you get this to work for the root.crt from CACert? With class3.crt, everything is fine, but the class1 cert (root.crt) does not appear in the list, anyway i try it.

    The class3.crt cert even appears when its named 00000000.0 (suggesting from another blog, where the author did not know where the hash comes from), but root.crt does not work with any name i tried. I tried even appending the output from “openssl x509 -noout -in root.crt -text”, like its done in the other android root-CA-certs, but its still not working.

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>