Inside Code Transparency: The Verification Process
A week ago, I looked at the contents of the JWT file created by the code transparency process. Today, let’s peek at how that gets verified.
Last week, when I showed you a
bundletool command to add code transparency, I used
a command that used a Java keystore directly. That does not seem to be an option for
the verification step. For that (or for adding code transparency), you need an
actual certificate file. You can obtain one from your keystore using
keytool -export \ -alias WhateverAliasYouUsed \ -keystore /path/to/your/keystore.jks \ -rfc \ -file /path/to/your/exported.cert
You can then use the
check-transparency command to verify the contents of… something.
--mode option indicates what the “something” is.
--mode=bundle says that you
are verifying an App Bundle, such as one created by you or your CI server:
bundletool check-transparency \ --mode=bundle \ --bundle=/path/to/your/AppBundleWithCT.aab \ --transparency-key-certificate=/path/to/your/exported.cert
If you leave off the
print the SHA-256 fingerprint of the certificate:
No APK present. APK signature was not checked. Code transparency signature is valid. SHA-256 fingerprint of the code transparency key certificate (must be compared with the developer's public key manually): 25 98 AA 59 62 BA 4C C0 7B 40 74 F4 19 09 02 A0 2A CD F1 1B 1F 42 84 92 93 23 8B 6F 87 E5 42 B4 Code transparency verified: code related file contents match the code transparency file.
This should match the one you get from
keytool -list \ -alias WhateverAliasYouUsed \ -keystore /path/to/your/keystore.jks
Alternatively, you can have
bundletool verify the code transparency for an installed app,
bundletool check-transparency \ --mode=connected_device \ --package-name=com.commonsware.scrap
As before, if you include
bundletool will check
against it; otherwise it will print the SHA-256 fingerprint.
Much of the code for code transparency support in
bundletool resides in
The core “driver” of the verification resides in a set of
ApkTransparencyCheckUtils. This code works off of a list of filesystem paths
to the APKs to check. Where those APKs come from depends on your
particular note, for
adb shell commands
to copy the APKs to a temporary directory for analysis – the verification is
not performed in situ on the device.
The code uses this JSON Web Toolkit library, which seems to be actively maintained, which is nice.
Unfortunately, the code for
bundletool seems to be fairly monolithic. It does not appear to be organized
as a library with a first-class API that also happens to have a CLI — it looks like it is
just a CLI. And, since
bundletool historically has only been needed for development
machines and CI servers, in many places it seems to assume that environment. Getting verification logic
that can run on-device will require reverse-engineering a spec from the implementation and creating a separate
library, unless Google has interest in a significant reworking of
The AndroidX Tech site contains source code, transitive dependency details, and much more for Google’s