04 May 2011

Android default (weak) signing configuration for the developer certificates


Some months ago I created a couple of Android applications.  As every Android developer  knows, in order to deploy applications on Android devices, these need to be signed. In other platforms like IOS, Symbian, Java or Windows Mobile, the signing process is a method used to prove the source of an application. Once an application is signed by a known certification authority, the platform will grant different execution permissions. Android  used code signing slightly different. The developer creates its own self signed certificate and uses this to sign any application he releases. This allows the platforms to recognize updates and also allow secure inter application communication.  The reason is simple, if there was no way to relate an application to its owner it would be trivial to impersonate him or her and deliver fake applications updates.

Without wanting to dig into the controversy between open and closed models, IOS vs Android, the part that caught my attention was that the developer would create a self signed certificate on his own and that that the only requirement is that the certificate must be valid until 2034. Today we all know that MD5 is proven to be weak and that key sizes should be at least 2048b, especially if we need to use it for a few years. On the other hand the default Android tools I used to create the certificate suggested to use a 1024b key and MD5 which is not a good idea, especially if that would be my identification until 2033!!

With that in mind I was curious to see how the digital certificates used to sign Android applications would look like. I analyzed nearly 4.000 applications, extracted the certificates and put together some statistics. For this I used unique certificates, which means that if two applications (in most cases these were updates) were signed with the same certificate I only took into consideration one occurrence.

First lets have a look at the algorithms being used:

As you can see the most used algorithm is RSA with SHA1 as a hashing algorithm but nearly one every 5 uses MD5 as a hashing algorithm. 
The strongest hashing algorithm found was SHA256 (1 occurrence, removed from the char) and the weakest MD5. It´s remarkable to see a 6% of DSA which is a n algorithm rarely used for X509 certificates, although perfectly valid.

Regarding key sizes for RSA we have the following distribution:

The most used key size is 1024b. Although I removed them from the pie charts, the weakest key size was 1023b (9 occurrences) and the strongest 8192b (1 occurrence). 

Developers, and some sysadmins too, tend to see digital certificates, and everything else around it, private keys, Root CAs, CRLs, etc as an annoyance and in the best cases as another “configuration” file.   Having in mind that Android forces you to use selfsigned certificates valid until 2033 it would be good to invest some time explaining developers the importance of the certificate/key and even more important enforce the use by default of stronger algorithms. Seeing the capabilities of the platform I don´t understand why Google did not enforce a minimum key length of 2048b and SHA1 or even better SHA256, instead of using default weaker settings especially when forcing developers to generate certificates valid for so long.