7

I'm using apksigner to verify the authenticity of a Google Podcast apk that I downloaded from an apk mirror. This apk (and older versions) verifies successfully (v1/v2/v3) and returns exit code 0 but in the output I see this warning:

WARNING: META-INF/services/com.google.protobuf.GeneratedExtensionRegistryLoader not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.

I do not understand what the impact of that is. If the APK is signed, and verified, why do I see this warning? Does it mean the APK could be trojaned or modified? How could an attacker exploit that?

I am downloading some older versions of some Google apps and I want to be sure they aren't trojaned, which is why I'm trying to verify the authenticity before I install them on my phone.

9

Summary

The warning you have encountered only applies to the APK signature v1, but as the APK file is signed with additional signatures of the newer signature schemes you can safely ignore this message as every modification on the APK file can be detected by the newer signature schemes.

However even if the signature can be verified it does not mean that the APK file is genuine. It still could be resigned after modification, therefore you should carefully compare the certificate digests (shown when verifying it using apksigner verify --verbose --print-certs) of the APK to be verified and compare it to other APK files of the same app developer. See this answer of How can I verify the authenticity of an APK file I downloaded? for details how to compare the certificate digest of an APK.

Detailed explanation

First of all as you can see what you get is a WARNING not an ERROR. If relevant file(s) of the APK file would have been modified the verification will fail and you would get an ERROR message.

To understand the warning message you need a little understanding of Java and how Java signatures (APK signature v1) work. This old signature is stored inside the JAR in two files: META-INF/CERT.SF and META-INF/CERT.RSA. Of course a signature can not sign the files it is written into , hence those files are excluded by the signature.

Additionally the META-INF directory is location of the MANIFEST.MF - a file that is only relevant for Java on Desktop but not used by Android at all.

There can be additional files in the META-INF directory, considering the standard Java directory layout no code should be stored inside files within the META-INF directory.

Because of all this Sun as the original inventor of Java decided to exclude the META-INF directory from the Java code signature at all. Several years later Google just used the Java signature for APK files which is now known as APK signature v1.

Therefore for the APK signature v1 the files inside the META-INF directory are not covered by the signature and hence can be modified without being recognized if you only verify

Because of several attacks on the APK signature itself (such as including the same file multiple times with different content in the APK Google decided to develop a completely new APK signature that does not apply on the APK content but on the overall APK file itself. This was the beginning of APK signature v2 and it's successors.

These new APK signature schemes do sign the complete APK content at once, not excluding a single file that is stored inside the APK file.

Back to the Google Podcast APK, verifying it using apksigner outputs the following:

java -jar apksigner.jar verify --verbose "Google Podcasts Discover free trending podcasts_v1.0.0.301897054_apkpure.com.apk"
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Number of signers: 1
WARNING: META-INF/services/com.google.protobuf.GeneratedExtensionRegistryLoader not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.

As you can see the APK file is signed not only by an v1 signature but also a v2, v3 and v4 signature. This means that the WARNING only applies to the signature created by the v1 scheme. You can easily verify that by modifying a single character inside the file META-INF/services/com.google.protobuf.GeneratedExtensionRegistryLoader as it is stored uncompressed within the APK file. You can simple open the APK file in an hex editor, modify a character in the section that belongs to that file (it is the first ZIP entry within the APK) and then again verify the APK:

java -jar apksigner.jar verify --verbose "Google Podcasts Discover free trending podcasts_v1.0.0.301897054_apkpure.com - modified.apk"
DOES NOT VERIFY
ERROR: APK Signature Scheme v3 signer #1: APK integrity check failed. CHUNKED_SHA256 digest mismatch. Expected: <ac8a15569352655a22f13d3c565c2c0e5c62dc70c8f6f8c10f6fbfa63decb19b>, actual: <aa5622cd904500c38424562ef4b5be9e5716d10a85985a41f35e4ed834cee8fe>
ERROR: APK Signature Scheme v3 signer #1: APK integrity check failed. VERITY_CHUNKED_SHA256 digest mismatch. Expected: <56eeebd545733fd6408cd6a30b8bcf98a557076167902b6d9502b5aca86b78e89b42220000000000>, actual: <c37e1e1436cfd62f89592c48211ffb6ad2f1dff0f69d2203072f1e6c3872a5919b42220000000000>

As you can see now the APK signature is considered invalid. I don't know why the v3 signature fails first, may be the signatures are not verified in order v1, v2, v3... From my understanding all signatures except v1 should fail on the modified APK file.

6
  • Thanks Robert (+1 for now ;)! Maybe you also want to point out that just because verify succeeds does not mean you've got no Trojan (or whatever) – as a completely different signing key might have been used? AFAIR jarsigner -certs -verify -verbose can be used to show details of the certificate used. But then, if the APK was downloaded to update an already installed app, Android would not accept the update if signatures do not match – so that would only be relevant to first-installs.
    – Izzy
    Nov 1 '20 at 11:18
  • 1
    @Izzy: Thanks Izzy, you are correct. I excluded this from my answer as it is already covered by the answer "newguy" has linked to in the question: android.stackexchange.com/a/218161/104486 hence I assumed that he is alerady aware of that topic, but for other users it might be still relevant.
    – Robert
    Nov 1 '20 at 11:21
  • Great, thanks! Especially using apksigner instead of jarsigner, so v2+ is covered as well. I'd upvote again, but not even a mod can do that :D
    – Izzy
    Nov 1 '20 at 13:06
  • Your answer is very helpful and I've marked it as correct. Thanks!
    – newguy
    Nov 3 '20 at 5:06
  • ...but what the "Verified for SourceStamp: false" means? Is it a security issue? Mar 26 at 7:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.