When you are surfing on Internet, one can still attempt to find out if a website is authentic or not. For websites we have the certificates, secure lock sign, complete URL etc. to help us know that the website is genuine and secure, is there an equivalent in Android App world?
As a user when I go to settings/App Info, all I can see is this:
See that there is no direct way to check an app's authenticity. For apps installed from Google play store, we do see a link to that app on playstore. But that's all there's no other info or validity proof.
How can one reliably check then that the app is authentic? Also, how do Android apps check that the other apps on the device that they are partnering with or exchanging infomation are authentic?
The answer lies in signing certificate info.
For such security reasons, all apps on Android need to be duly signed before they can be deployed on playstore.
So, having talked about why we need App Signing. Let's dive deep into what is app signing, how can it be done and how does it functions to ensure authenticity of the app?
Applications are signed inmost operating systems.
According to Android Documentation:
"Application signing allows developers to identify the author of the application and to update their application without creating complicated interfaces and permissions. Developers know their application is provided, unmodified, to the Android device; and developers can be held accountable for behavior of their application."
On Android, application signing is the first step to placing an application in its Application Sandbox. The signed application certificate defines which user ID is associated with which application; different applications run under different user IDs. Application signing ensures that one application cannot access any other application except through well-defined IPC
Android provides code signing using self-signed certificates that developers can generate without external assistance or permission. Applications do not have to be signed by a central authority.
Android supports three application signing schemes:
v1 scheme: based on JAR signing
This is based on Signed JAR. the thing to note here is that v1 signatures do not protect some parts of the APK, such as ZIP metadata. The APK verifier needs to process lots of untrusted (not yet verified) data structures and then discard data not covered by the signatures. This offers a sizeable attack surface. Moreover, the APK verifier must uncompress all compressed entries, consuming more time and memory. To address these issues, Android 7.0 introduced APK Signature Scheme v2.
v2 scheme: APK Signature Scheme v2, which was introduced in Android 7.0 & v3 scheme: APK Signature Scheme v3, which was introduced in Android 9
Devices running Android 7.0 and later support APK signature scheme v2 (v2 scheme) and later. (v2 scheme was updated to v3 in Android P to include additional information in the signing block, but otherwise works the same.) The contents of the APK are hashed and signed, then the resulting APK Signing Block is inserted into the APK.
Apps can be very simply signed by Android Studio options or command line.
Open Android Studio, go to Build > Generate Signed APK.
You can follow steps put here :
https://developer.android.com/studio/publish/app-signing#sign-apk
to generate a signed key. There are options when you can opt for Google Playstore signing every release. Check out that link.
Simple commands to generate a key and view the contents are as below:
Generate:
keytool -genkey -v -keystore <keystorealias> -storepass <keyStorePassword> -alias <keyAlias> -keypass <keyPassword> -keyalg RSA -keysize 2048 -validity 30000
View:
keytool -list -v -keystore <keystorealias> -alias <keyAlias> -storepass <keyStorePassword> -keypass <keyPassword>
PS: Replace the bold italic variables with actual values. Setup the values for algorithm to be used to generate the key, keysize and validity (in days). as per your use case.
Also, check out APKSigner and ZipAlign tools that come handy (not covering them in this post but they're worth exploring).
Something like this can be done.
public boolean validateAppSignature(Context context) throws NameNotFoundException {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo( getPackageName(), PackageManager.GET_SIGNATURES);
//note sample just checks the first signature
for (Signature signature : packageInfo.signatures)
{ // SHA1 the signature
String sha1 = getSHA1(signature.toByteArray());
// check is matches hardcoded value
return APP_SIGNATURE.equals(sha1);}
return false;}
When an application (APK file) is installed onto an Android device, the Package Manager verifies that the APK has been properly signed with the certificate included in that APK. If the certificate (or, more accurately, the public key in the certificate) matches the key used to sign any other APK on the device, the new APK has the option to specify in the manifest that it will share a UID with the other similarly-signed APKs.
What might happen if devs private signing key gets lost?
The older app cannot be updated! It results into a new package name & a new certificate altogether. As an example:
A private application signing key was lost or compromised for Authenticator app, which received an update that changed its package name from com.google.android.apps.authenticator to com.google.android.apps.authenticator2 in an update few years ago. Due to this change, all subsequent Authenticator app updates could only be issued under the new package name–with the new signature generated by the new private signing key.
Although, recently Google has also added support for "rolling keys" that might save devs some stress in such troublesome situations.
So that's all for this post folks, hope you found it resourceful. Signing is a crucial scenario that needs to be well understood in order to understand the overall security landscape of Android and hence this first post on the topic.
We'll dive deeper into related security concepts in the coming posts soon. Let's learn about TEE? What say?
Let me know how you liked this post. Please share/like/subscribe if you like it so.
For more engaging discussions let's connect on Twitter.
Take care & keep hacking! <3