How much do you know about the apps running on your mobile device? Different mobile operating systems, such as Android and iOS, enforce different disciplines. For example, Android apps can be signed with a self-signed certificate rather than with a trusted certificate authority. In many cases when it comes to signing or packaging apps, developers just satisfy the bare minimum requirements to get an app in an app store. So how do you find out what they’ve done? In this post I share how you can examine apps installed on your Android phone (and without even having to root it).
I wanted to learn more about the apps installed on my own Android phone, so I decided to look at the Android application programming interfaces (APIs).
Obtaining the list of packages
With Android’s PackageManager API, there is a method for getting installed packages (getInstalledPackages). This method enables you to get a listing of all the packages installed on the device. Depending on the flag passed to this method, it will return different information. However, for the purpose of this article I will pass the PackageManager.GET_SIGNATURES flag.
PackageManager pm = this.getPackageManager();
List<PackageInfo> infoList = pm.getInstalledPackages(PackageManager.GET_SIGNATURES);
Obtaining application information
A package has many attributes that we can harvest and examine. In addition, each package belongs to an application. The PackageInfo class allows you to obtain a rich set of app characteristics. From PackageInfo you can extract information from the application tag by accessing ApplicationInfo variable.
ApplicationInfo appInfo = pkgInfo.applicationInfo;
The ApplicationInfo attributes that seemed of interest to me are:
You might be interested in others.
Obtaining package information
The PackageInfo attributes that seemed of interest to me are:
Obtaining package signatures
Package signatures are the X.509 signatures found in the application packaging. This is a result of signing an app with a certificate. From package signatures I can determine if a self-signed certificate was used to sign the app and its attributes.
Signature signatures = packageInfo.signatures;
For each Signature object obtained, load the certificate so that its attributes can be parsed:
byte cert = signatures[i].toByteArray(); InputStream input = new ByteArrayInputStream(cert); CertificateFactory cf = cf = CertificateFactory.getInstance("X509"); //certificates are of type X.509 X509Certificate c = (X509Certificate) cf.generateCertificate(input);
From the X509Certificate object I can access, through getter methods, all the attributes of the certificate, such as subject or issuer Distinguished Name (DN), validity period and so on. Here are the ones I found interesting:
For more on X.509 certificate attributes and their purpose, see this Wikipedia entry.
When I put this all together, I get generic and security information about the application. Analyzing this information can yield some interesting observations about each app you have on your mobile device. In a future post I will share observations about applying this analysis to apps on my phone.
What can you do with the knowledge you’ve extracted from each app? Connect with me on Twitter @tearoks and share your thoughts.