Skip to content

APK Signing Block considerations

See https://android.izzysoft.de/articles/named/iod-scan-apkchecks#blobs


Some considerations regarding the APK Signing Block and how F-Droid handles Reproducible Builds.

Block types

APK Signature Scheme Block

The signature part of the APK Signing Block can contain more than one signature.
AFAIK android and apksigner (unlike apksigtool) only check the one with the strongest supported signature algorithm ID, not all of them.
So it might be possible to hide some data in a signature that won't be checked normally.

Either way it's possible for the app to behave differently depending on which key it was signed with, though we can't do much about that.

Related: Android App Links.

Frosting and SourceStamp Blocks

These opaque Google-specific extensions have their own block types.
There is some documentation, code, and reverse engineering, but in the end we don't really know what's in there.

Dependency Info Block

Another opaque Google-specific extension.

"[...] data is compressed, encrypted by a Google Play signing key [...]"

Pretty much no useful search results

dependencyinfoblock-search

Any other block types

AFAIK these are simply ignored by apksigner etc.
So a developer could just create their own block type (or abuse an existing one) and put anything they want in there, including code.

Security

Android apps have access to their own APK file (e.g. I can run apksigcopier extract in Termux on Termux' own APK in /data/app/), so AFAIK an app could easily load some kind of code/instructions from the Signing Block, especially from something other than the APK Signature Scheme Block.

I haven't made a PoC for this yet, but it's on my TODO list somewhere.

What to do?

  • Apps signed by F-Droid should be "safe".
  • Apps using signatures in metadata could already have put something additional in the APKSigningBlock, but there is some accountability via git history.
  • Apps using Binaries: -- or the server we download the APK from -- could put anything additional in there.

I'd recommend at least "cleaning" and/or "linting" the APK Signing Block as part of our build process / CI, allowing only APK Signature Scheme Blocks (and verity zero padding), and ideally making sure all signatures in there are valid.

The downside to "cleaning" (when it actually removes something) is that it results in an APK file that verifies correctly, but will not have the same checksum as the original since the APK Signing Block differs.

Current apps using signatures in metadata seem to be "clean":

Output
$ for file in $( find -name APKSigningBlock ); do apksigtool clean --block "$file"; done | uniq -c
     37 nothing to clean

$ for file in $( find -name APKSigningBlock ); do apksigtool parse --block --json "$file" | jq -r '.pairs[].value._type'; done | sort | uniq -c
     72 APKSignatureSchemeBlock
     35 VerityPaddingBlock

However, two apps using Binaries: have a DependencyInfoBlock (encrypted by a Google Play signing key).

Output
$ for file in *.apk; do echo "==> $file"; apksigtool parse --json "$file" | jq -r '.pairs[].value._type'; echo; done
==> androdns.android.leetdreams.ch.androdns_15.apk
Error: No APK Signing Block.

==> androdns.android.leetdreams.ch.androdns_16.apk
Error: No APK Signing Block.

==> ch.admin.bag.covidcertificate.verifier_4040000.apk
APKSignatureSchemeBlock
DependencyInfoBlock
VerityPaddingBlock

==> ch.admin.bag.covidcertificate.verifier_4060000.apk
APKSignatureSchemeBlock
DependencyInfoBlock
VerityPaddingBlock

==> ch.admin.bag.covidcertificate.verifier_4070000.apk
APKSignatureSchemeBlock
DependencyInfoBlock
VerityPaddingBlock

==> ch.admin.bag.covidcertificate.wallet_4040000.apk
APKSignatureSchemeBlock
DependencyInfoBlock
VerityPaddingBlock

==> ch.admin.bag.covidcertificate.wallet_4060000.apk
APKSignatureSchemeBlock
DependencyInfoBlock
VerityPaddingBlock

==> ch.admin.bag.covidcertificate.wallet_4070000.apk
APKSignatureSchemeBlock
DependencyInfoBlock
VerityPaddingBlock

==> com.mishiranu.dashchan_1041.apk
APKSignatureSchemeBlock
VerityPaddingBlock

==> com.mishiranu.dashchan_1042.apk
APKSignatureSchemeBlock
VerityPaddingBlock

==> com.mishiranu.dashchan_1043.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> de.corona.tracing_2240202.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> de.corona.tracing_2250002.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> de.corona.tracing_2260004.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> de.schildbach.oeffi_120025.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> de.schildbach.oeffi_120100.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> de.schildbach.oeffi_120103.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> eu.bubu1.fdroidclassic_1014.apk
Error: No APK Signing Block.

==> eu.bubu1.fdroidclassic_1106.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> eu.bubu1.fdroidclassic_1110.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> info.guardianproject.checkey_101.apk
Error: No APK Signing Block.

==> nya.kitsunyan.foxydroid_2.apk
Error: No APK Signing Block.

==> nya.kitsunyan.foxydroid_3.apk
Error: No APK Signing Block.

==> nya.kitsunyan.foxydroid_4.apk
Error: No APK Signing Block.

==> org.briarproject.briar.android_10410.apk
APKSignatureSchemeBlock

==> org.briarproject.briar.android_10411.apk
APKSignatureSchemeBlock

==> org.briarproject.briar.android_10412.apk
APKSignatureSchemeBlock

==> org.jellyfin.mobile_2040199.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> org.jellyfin.mobile_2040299.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> org.jellyfin.mobile_2040499.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> rs.ltt.android_12.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> rs.ltt.android_13.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> rs.ltt.android_14.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> top.fumiama.copymanga_23.apk
APKSignatureSchemeBlock
APKSignatureSchemeBlock
VerityPaddingBlock

==> uk.co.keepawayfromfire.screens_6.apk
APKSignatureSchemeBlock

==> uk.co.keepawayfromfire.screens_7.apk
APKSignatureSchemeBlock

==> uk.co.keepawayfromfire.screens_8.apk
APKSignatureSchemeBlock

Related: #1055 (closed), #974, #1013, #935.

Edit 1: added apksigtool clean & apksigtool parse output for apps using signatures in metadata.
Edit 2: added apksigtool parse output for apps using Binaries: and Dependency Info Block section.

Edited by FC (Fay) Stegerman
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information