Inspecting application certificates and signatures
Application certificates are what developers use to declare their trust in the applications they publish to the application market. This is done by declaring their identities and associating them to their application(s) cryptographically. Application signatures make sure that no application can impersonate another by providing a simple and effective mechanism to determine and enforce the integrity of Android applications. It is a requirement that all applications be signed with certificates before they are installed.
Android application signing is a repurposing of JAR signing. It works by applying a cryptographic hash function to an application's contents. We will soon see exactly which of the contents in the APK files are hashed. The hashes are then distributed with a certificate that declares the developer's identity, associating it to the developer's public key and effectively, his/her private key, since they are related semantically. The certificate is usually encrypted using the developer's private key, which means it's a self-signed certificate. There is no trusted third party to vouch for the fact that the developer actually owns the given public key. This process yields a signature and is to be distributed or published with this public key.
An application's signature is unique and finding an application's certificate and signature is a crucial skill. You may be looking for malware signatures on a device, or you may want to list all of the applications that share a given public key.
Getting ready
Before we begin, you will need the following software installed on your machine:
- Java JDK: This can be installed on either Unix/Linux distribution or Microsoft Windows system, as shown in the previous chapter
- Android SDK: This can be installed on your Linux Debian or Microsoft Windows system, as shown in the previous chapter
- WinZip (for Windows): This is available for download at http://www.winzip.com; if you are running Windows 7, WinZip is not explicitly required
- Unzip (for Debian/Ubuntu Linux systems): This can be installed by typing the following command into your terminal:
sudo apt-get install unzip
Assuming that we don't already have an application in mind—whose certificate you would like to view—and given that you'd like to be able to completely replicate what is demonstrated here, it'd be convenient to pull an app of an emulator. This recipe also details setting up the emulator to do so.
Setting up an emulator, in the way it is done here, ensures that you will be able to get access to exactly the same applications and emulated system, and ultimately, the same certificates, making it easy to check that you're on the right track. Before you can emulate an Android device, you will need to make sure the Android SDK tools are updated to include the latest API levels and emulator images. If you're not sure how to upgrade your Android SDK, please refer to the previous chapter.
So, to start off, lets fire up an Android Virtual Device (AVD) by performing the following steps:
- Open a command-line interface and execute the following command:
[path-to-your-sdk-install]/android create avd –n [your avd name] –t [system image target]
Or if you're using a Windows machine, type:
C:\[path-to-your-sdk-install]\android create avd –n [your avd name] –t [system image target]
- If all goes well, you should have just created an AVD. You can now go ahead and launch it by executing the following command:
[path-to-your-sdk-install]/emulator –avd [your avd name] –no-boot-anim
- You should see an emulator pop up almost immediately. You will need to give it a second to boot up. Once it's all booted and you can see the lock screen, it means you can fire up ADB and pull some APK files off for us to dissect. You can pull an APK file off by typing the following command:
adb pull /system/app/Contacts.apk
See the following screenshot for a practical example:
You can find the Contacts app or others, should you need another example to work with, by checking out the contents of the
system/app/
directory, as shown in the following screenshot:You should have just copied over the Contacts app onto your local device. If any of this is confusing, please refer to the previous chapter; it covers how to create an emulator and copy devices from it.
How to do it…
You should have a local copy of the APK files that you wish to inspect on your hard drive. We can now begin inspecting the application's certificate. To view an application's public key certificate and signature, you will first need to unpack the APK file. This is pretty easy if you know how to unzip an archive because APK files are in fact ZIP archives that have been renamed. You can unzip the archive by performing the following steps:
- If you're on a Windows machine, you may need to make sure that you have WinZip installed. All you need to do is open the APK file using WinZip, and it should open like any other ZIP archive. On Linux Debian machines, you will need to copy this file to a file with a ZIP extension so that WinZip will happily unzip it for us:
cp Contacts.apk Contacts.zip
- Unzip the archive to some memorable place; you can do that by firing off the following command:
unzip Contacts.zip
After unzipping the archive, your directory should look like the following screenshot:
- Locate the folder called
META-INF
. This folder contains the signature file and the actualCERT.RSA
file which is the self-signed public key certificate; you can view it using the keytool that comes bundled with the Java JDK that you should have installed prior to attempting this recipe. Use the following command to print the certificate:keytool –printcert –file META-INF/CERT.RSA
What you have in front of you now is the certificate that declares the holder of the public key.
- To view the actual signatures related to the application content, locate a file called
CERT.SF
under theMETA-INF
folder. You can view this on Windows by opening it in notepad or any other text editor that is available to you, or on Unix/Linux machines by executing the following command:cat [path-to-unzipped-apk]/META-INF/CERT.SF
You should have the signature file in front of you now. It includes the cryptographic hashes of the resource files included in the application; see the following screenshot for an example:
This file is used when the
jarsigner
tool tries to verify the content of the application; it computes the cryptographic hash of the resources listed in theCERT.SF
file and compares it to the digests listed for each resource. In the previous screenshot, the hash—SHA-1 Digests
—have been base64 encoded.
How it works…
The META-INF
folder is a very important resource because it helps to establish the integrity of the application. Because of the important role the contents of this folder plays in the cryptographic security of an application's content, it is necessary to discuss the structure of the folder and what should appear inside it and why.
Inside the META-INF
folder, you should find at least the following things:
MANIFEST.MF
: This file declares the resources very similar to theCERT.SF
file.CERT.RSA
: This is the public key certificate, as discussed previously.CERT.SF
: This file contains all of the resources in the application that have been accounted for in the application signature. It is added to accommodate JAR-specific cryptographic signing.CERT.RSA
: This is a X.509 v3 certificate; the information in it is structured by keytool in the following way:- Owner: This field is used to declare the holder of the public key, and it contains some basic information about the country and organization associated to this individual.
- Issuer: This field is used to declare the issuer of the X.509 certificate that associates the public key to the declared holder. The people or organizations mentioned here are the ones that effectively vouch for the key holder. They are the ones that establish the authenticity of the public key listed in the certificate.
- Serial number: This is used as an identifier for the issued certificate.
- Valid from ... until: This field specifies the period for which this certificate and its associated attributes can be verified by the issuer.
- Certificate fingerprints: This field holds the digest sums of the certificate. It is used to verify that the certificate has not been tampered with.
The digital signature is computed by encrypting the certificate with the trusted third parties' private key. In most Android applications, the "trusted third party" is the developer. This means that this signature is generated by encrypting the certificate using his/her own private key—usually the one associated to the public key. This usage of the digital signature may be functionally correct—it makes functional use of the digital signature mechanism—but it isn't as robust as relying on a trusted third party like a Certificate Authority (CA). After all, anyone can say that they developed the Twitter app by signing it with their own key, but no one can say that they own VeriSign or Symantec's private key!
If the certificate is self-signed, the developer can exercise his/her creativity while filling out the information associated to the certificate. The Android package manager makes no effort to verify that the issuer, owner, or any other details of the certificate are valid or are actual existing entities. For instance, the "owner" doesn't explicitly need to mention any valid personal information about the developer, or the "Issuer" could be a completely fabricated organization or individual. Though doing this is possible, it is strongly recommended against because it makes an application very hard to trust; after all, a mobile application is often stored and used on a very personal device, and people who become privy to the fabricated details of a public key certificate may no longer trust such an application.
The best way to go about generating a trustworthy application certificate is through a qualified CA by either requesting a signed public key certificate—after generating your own public and private key pair—or requesting a CA to generate a public/private key pair with a public key certificate, since they will often verify all of the information published in the certificate. Symantec and other CAs and security vendors often offer a range of services to facilitate the generation of trustworthy public key certificates, some of which are catered to supporting Android application development.
The next recipe of this walkthrough contains some useful links on public key certificates for you to check out.
There's more...
You can also view the full public key certificate using the OpenSSL library via the command-line tool on Linux by performing the following steps:
- Make sure you have OpenSSL installed; if not, you can install OpenSSL with the following command:
apt-get install openssl
- Once installed, you can view the certificate using the following command, provided you are in the root of the unzipped
APK
directory:openssl pcks7 –inform DER –in META-INF/CERT.RSA –noout –print_certs –text
You should see something like the following screenshot appear on your terminal screen:
The second half of the previous screenshot is as follows:
The last section of the certificate in the previous screenshot is the actual digital signature of the CA that issued the certificate.
See also
- The RFC2459 – Internet X.509 Public Key Infrastructure Certificate and CRL Profile document at http://datatracker.ietf.org/doc/rfc2459/?include_text=1
- The X.509 Certificates and Certificate Revocation Lists (CRLs) Oracle documentation at http://docs.oracle.com/javase/6/docs/technotes/guides/security/cert3.html