Android root Certificates Management

This post is not about root certificates. It is not analyzing the different formats of security certificates neither how to generate those.

This post is about how Android deals with security certificates and how to change it to make it more secure. Android v4.1+

There are mainly two source files you want to check to understand this better (NativeCrypto.java and TrustedCertificateStore.java). This is all part of the Apache Harmony for Android Open Source Project.

Android, as any other mobile operating system has a CA root security certificates store that uses to validate the identity of remote peers. It is the same way as an internet browsers does. There is a directory (/etc/security/cacerts), where Android stores the root certificates. This is called the Certificates Store. When an application contacts a remote server, this sends it’s identity to the Android device. Then Android validates it or rejects it based on the trusted certificates stored in the Certificates Store.

Root Certificates are formatted in PEM. They include also the human readable version of it. The way Android name these certificates is by using an MD5 hash, based on the unique subject name field of the certificate. This means that the name of the file for the certificate with Subject field equals to “C=US, O=GeoTrust Inc., CN=GeoTrust Global CA” is 7999be0d.0

As we can see in the next code from TrustedCertificateStore.java, the search method will first request the MD5 hash and then will perform the search on the Certificates Store.


private String hash(X500Principal name) {
    int hash = NativeCrypto.X509_NAME_hash_old(name);
    return IntegralToString.intToHexString(hash, false, 8);
}

How to make this more safe

There are some things you can do if you want your Android to be more safe. And there are reasons for this.

MD5 hash algorithm is broken. It is surprising that Google still uses this MD5 hash algorithm. This is something that is totally broken and nobody should use it anymore. Apache Harmony provides another method to calculate the SHA1 instead of MD5.  To do this:

  1. Use NativeCrypto.X509_NAME_hash(name); instead of NativeCrypto.X509_NAME_hash_old(name);
  2. Rename all your certificates to use a SHA1 based name. Watch out here if you use openssl to do this. Openssl generates a different SHA1 hash than the Apache Harmony framework. Why? Apache Harmony bases the MD5 and SHA1 hash in the Subject name of the certificate. Before computing the hash, it transform that subject string into a ASN1 DER format. This is done for both MD5 and SHA1 and is pretty standard across different frameworks.

The openssl command line tool does not behaves like that. Encryption is like money laundry, the more hands you can pass the money through, the harder in theory to track it back to the originator. Openssl folks correctly believed that SHA1 was not safe enough so they decided to pass it through one more filter. It first calculates the CANONICAL format of the string. Then you take that String and generate the ASN1 DER format of it. Then it passes the encoded string to the SHA1 algorithm to calculate the digest. Yeap, pretty nasty. I believed that openssl.1.0.1e libraries already include all these changes. But if you are using older ones you will have to modify them to be able to programmatically calculate the SHA1 of a certificate. You can read a little bit more about how to do this in this thread from the openssl mailing list

I hope that eventually, better sooner than later, Google decides to go for at least SHA1. At this point SHA1 is no safe either but hey, it’s better than MD5.

Advertisements

3 Responses to “Android root Certificates Management”

  1. Still very helpfull post, that I can’t believe noone have not commented on yet. Thank you for the brief yet explaining material.

  2. To be fair though, md5 is broken only with regards to the ease of finding collisions. However, it is still pretty good against preimages attacks, which is needed to masquerade as a valid cert. This is probably why Google still uses it.
    But i still agree that md5 probably shouldn’t be used as its preimage resistance is probably not gonna be good by the end of the decade.

Trackbacks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: