A rebuilt file cannot contain the original signature, because only the key holder can make it. So you either paste the signature into the rebuild, compare while ignoring the signature, or strip the signature from the release. All three are documented ways to check a signed artifact against a rebuild.
Why signing breaks naive comparison
Some software ships with an embedded cryptographic signature, such as a signed Android APK. By definition, a rebuilder cannot generate an identical signature. If you compare checksums of the official release and your rebuild, they will always differ.
The Reproducible Builds documentation lists three ways to handle this.
| Approach | How it works | Trade off |
|---|---|---|
| Pasting signatures | Make the signature an optional input to the build. The developers sign once, store the signature outside the binary, and the build copies it into place | Needs build support; keeps verification byte for byte |
| Ignoring signatures | A comparison tool skips the signature bytes | The tool must be very easy to audit, or you cannot trust it is not skipping more |
| Stripping signatures | Ship a tool that removes the signature from the official release, then compare with your build | You must download the release; harder to show that removed data does not change behaviour |
The docs name two examples of pasting: the wireless-regdb package in Debian, and F-Droid's use of APK signature copying with apksigcopier.
How F-Droid does it for APKs
F-Droid's reproducible builds page describes the process. It verifies a rebuild by copying the signature from a signed APK onto an unsigned one, then checking the result verifies.
It also explains why older and newer Android signatures behave differently. The old v1 JAR signatures cover only the contents of the APK, so ZIP metadata and ordering do not matter. The v2 and v3 signatures cover all other bytes in the APK. So the APKs must be completely identical before and after signing, apart from the signature, or verification fails. F-Droid says signature copying uses the same algorithm as apksigner, so upstream developers should sign with apksigner.
The page also gives practical context for Android teams. Java code often compiles to the same bytecode across a range of Java versions. Android SDK build tools can create differences in XML and PNG files, which is usually manageable because build.gradle pins the build tools version. Native code built with the NDK is much more sensitive; even the same NDK version on different platforms produced different binaries. And starting with Gradle Android Plugin 2.2.2, timestamps in the APK's ZIP metadata are zeroed.
What an app team can do
- Decide which of the three approaches fits your release format.
- Sign as the last step, with a tool that does not alter the bytes it signs. Keep signing separate from the build.
- Store the signature, or a way to strip it, with the release.
- Pin build tools and the NDK version, and build native code in a controlled environment.
- Publish a checksum of the unsigned artifact as well as the signed one.
- Have someone outside your build system rebuild and compare, at least for important releases.
A caution about what this proves
A match shows that the signed release corresponds to your declared source and build instructions. It does not show the source is free of flaws, and it does not replace dependency scanning.
Quick check
Can I verify a signed APK by comparing hashes?
Not directly. The signatures differ. Copy the signature onto the unsigned rebuild, or use a comparison that accounts for it.
Does it matter which tool signs the APK?
F-Droid says signature copying uses the apksigner algorithm, so developers should sign with apksigner for verification to work.
Safeguard's SBOM and dependency scanning is generally available. The free scan at gold.safeguard.sh/scan covers a repository's dependencies.
Sources
Last reviewed: 19 October 2026.