Photo by Digital Buggu from Pexels
Google announced Android App Bundles a couple of years ago at I/O 2018. App Bundles are a new app publishing format providing new features that have rapidly driven their adoption. In particular App Bundle delivery enables automatic splitting of various assets within the overall app package, so they are only delivered to a device if they are actually needed.
This significantly reduces app install times, data and storage used. Bulky native libraries are only sent to the devices with the corresponding architecture, graphics resources are customized to the device resolution and language packs are only sent if relevant languages are selected. Moreover, there are even more advanced features to enable dynamic delivery of particular app features on demand, avoiding the overhead of initial download.
The venerable APK format has been with us since the inception of Android. If you created an app for the store, signed it and then uploaded it, then it would be delivered verbatim to all of the devices that downloaded it. At this time the Play Store was essentially a big file store with an elaborate shop window. A couple of years after the APK Signature scheme V2 was introduced, Google commenced also signing the APK to show that the app had indeed come from the official app store. The additional signature is inserted into the APK's signing block, outside of the compressed part of the APK file. Thus the zipped body of the APK remains exactly as you had published it.
An App Bundle (.aab file) uploaded to the Google Play Console is automatically partitioned into a set of different individual APK files. When an individual device wants to download an app, the store examines its capabilities and determines the correct set of individual APKs that go together for the device. When your app is running it is actually composed of various different APKs mapped into the address space of the app.
One of the key guarantees that Approov provides is that, in order to obtain a valid token, the request must be coming from an official version of your app. You register your APK before it goes to the store to demonstrate it is an official version. We do numerous checks, but a key one is to calculate the APK signature of the running app to ensure it is an official version. If we cannot rely on the content of the APK being consistent across all devices then this is obviously somewhat problematic. Up until now our flow has required you to upload your production App Bundle, and then download the generated base.apk that is the core of the app and will typically contain all of the application DEX code. This APK can then be registered in the normal way, since we know it will be delivered to all devices. However, we realise that having to go through a manual step in the Google Play Console is cumbersome.
Thus from version 2.3 of Approov onwards we provide significantly enhanced support for App Bundles. The Approov CLI is able to register .aab files directly before you upload them to the Google Play Console. You don’t need to download anything from the console itself. To use this feature you must have an SDK version 2.3.0 or later, and you also need to download the Android bundletool as described here. You also need to tell Approov about the App Signing Certificates that are associated with your releases. You will need to access the Google Play Console for these, but only once during your setup.
So how does our App Bundle support work?
Going back to the app installation process - when a user first installs an app, Android calculates the digests of the delivered APKs and checks them against the entries in the signature block of the APK. This block includes signatures calculated using Google Certificates. If the signatures correctly correspond to calculated digests then this proves that the integrity protected content has not been modified since it was signed, and the certificate chain proves that the app was indeed signed by Google and thus it went through the app store. This allows the app to be installed. The app will also be countersigned using your development certificate to prove its origin, and to restrict app updates to the original app developer. Normally this process only happens once on installation.
Our Approov support essentially repeats this process whenever the app is launched. We examine the running app, and calculate the digest of the integrity protected content again. This is done in an optimized and low level manner to prevent any spoofing of the APK images by an advanced attacker. The digest and contents of the signature block are then transmitted to the Approov cloud. From this we are able to verify that the digest matches the expected signature from your App Development certificate, just using the public key. In other words, we prove it is your app and nothing has tampered with it.
If these signature checks pass, along with the numerous other checks we do, then we supply your app with a valid Approov token. From there it can pass this to backend APIs to prove that it really is authentic. This delivers proven app integrity, from the first principles of the integrity of your app package, on every API call your app needs to make.