To say, APKs can never be reproducible because of the signature is disingenuous. Reproducible builds are about binary transparency and while technically you could argue if an app is reproducible when the provider packed a signature into the file and you managed to reproduce all but these 64B, it's a moot point as the important part is the binary transparency of the executable code. Now you could say that the signature might contain evil code, right? Then the rest of the app would still need to invoke that code. So yes, maybe there is a backdoor in the signature but as long as the signature is exclusively uses as signature, it won't work as a backdoor. And if some part of the app uses its signature in some creative non-signature way, auditors should scream foul regardless of what the signature is. The other problem with relaxing the definition of reproducibility is the package format. In Android, APK files are basically zip files but not quite. APK uses zip compression but also has extra data like the signature itself. But absent a flaw in the operating system, that extra data is not available to the app during runtime, so binary transparency is possible under some assumptions.
Thanks clarifying, was not aware that the signature can be that easily separated. Does that mean that in case there is a reproducible build method available I can take an apk, unpack and try to reproduce just the binary?
*take the .apk, unpack, remove the signature and try to reproduce the rest of the binary
In the case of Android the approach we use is to compile the apk ourselves and then compare the results. Comparing involves unzipping both apks and then comparing file by file. This is necessary as zip compression can result in different bits depending on the version of zip being used but the uncompressed data matches. We also use diffoscope that provides more insight into signing blocks that are in parts that normal zip tools might ignore. A different approach is to compile the app, extract the signature from the official app, add the signature to the compiled app and then verify the signature. If it's valid, the file is reproduced with only the signature coming from the official file. In the case of hardware wallets, the signature is typically a block of binary at the start or the end of the file, too. We shift the burden of verification if other stuff might reside there and do harm to those that do actual code audits, which we do not provide at this point.
Great work, thank you! In the meantime was just browsing your page for Aqua wallet: https://walletscrutiny.com/android/io.aquawallet.android/
Yes, the app is quite popular for such a young product but not huge yet neither. I guess they'll figure it out soon. Looking forward to seeing it reproducible.