Skip to content

Instantly share code, notes, and snippets.

Last active Apr 19, 2021
What would you like to do?
[draft] apksigcopier abstract

F-Droid is "an installable catalogue of FOSS (Free and Open Source Software) applications for the Android platform." [1] All applications are built by the F-Droid build server from source. Usually they are then signed by F-Droid, but F-Droid also "supports reproducible builds of apps, so that anyone can run the build process again and reproduce the same APK as the original release. This means that F-Droid can verify that an app is 100% free software while still using the original developer’s APK signatures." [2,3]

In order to verify that the APK built by the build server is identical to the one signed by the (upstream) developer, the signature from the signed APK is copied to the unsigned APK and the APK with the copied signature is verified.

The older v1 (JAR) signing scheme used a signature that guaranteed integrity of the contents of the APK (which uses the ZIP file format) only. Differences in ordering, metadata, or extra bytes ignored by the ZIP format were irrelevant. This made copying the signature very easy, but provided only partial guarantees of integrity that have been shown to be exploitable in the past.

The newer v2/v3 signing scheme uses a new signature scheme [4] that adds a "signature block" between the ZIP entries contents and the ZIP central directory. This signing block guarantees the integrity of every byte in the APK (apart from the signing block itself). This makes for much stronger guarantees of integrity, but results in making copying the signature much more difficult since it needs to generate completely bitwise identical ZIP files.

In order to copy v2/v3 signatures properly, we've developed apksigcopier [5], which implements the same algorithm that apksigner uses to copy an APK when signing it. This allows us to successfully copy APK signatures from a signed APK to an unsigned one (as long as the unsigned APK that was built and subsequently signed by the (upstream) developer was bitwise identical to the unsigned APK that was built by the build server).

Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment