-
Notifications
You must be signed in to change notification settings - Fork 66
AndroidPackageSignatures
Android APK packages are signed in almost the same way Java jar files are signed. Both APK and normal jar file are a collection
of files contained in a zip archives. This zip file contains a special directory called META-INF. You can list the content
of an apk or jar by unzipping it.
unzip -l com.rovio.angrybirds.apk
Archive: com.rovio.angrybirds.apk
Length Date Time Name
--------- ---------- ----- ----
62857 2011-02-07 17:12 META-INF/MANIFEST.MF
62910 2011-02-07 17:12 META-INF/CERT.SF
1714 2011-02-07 17:12 META-INF/CERT.RSA
55050 2011-02-07 17:10 assets/data/audio/sfx/redbird_yell03.wav
806436 2011-02-07 17:12 assets/data/images/864x480/MENU_ELEMENTS_1.pvr
24278 2011-02-07 17:10 assets/data/audio/sfx/wood damage a1.wav
6027 2011-02-07 17:12 assets/data/levels/pack6/LevelP3_224.lua
60572 2011-02-07 17:10 assets/data/audio/music/game_complete.mp3
253792 2011-02-07 17:12 classes.dex
--------- -------
35780825 653 filesMETA-INF/MANIFEST.MF contains the list of files present in the APK and their
digest of their content. The default digest used is
SHA-1 its representation in the the
manifest is the base64 encoded binary value (unix tools like sha1sum or openssl
sha1 display the hexadecimal encoded binary value)
Manifest-Version: 1.0
Created-By: 1.0 (Android SignApk)
Name: assets/data/audio/sfx/redbird_yell03.wav
SHA1-Digest: 5bu0IsTrS29K1B/cZohBUYZx5tk=
Name: classes.dex
SHA1-Digest: edkyVsHyY7d4Y7TFgGhazz6PypY=META-INF/CERT.SF (Signature file) In the manifest file, the SHA digest value
for each source file is the digest (hash) of the binary data in the source file.
In the .SF file, on the other hand, the digest value for a given source file is
the hash of the three lines in the manifest file for the source file. The lines
are “dos” terminated.
e.g.
"
Name: assets/data/audio/sfx/redbird_yell03.wav
SHA1-Digest: 5bu0IsTrS29K1B/cZohBUYZx5tk=
" | sha1sum | awk '{print $1}'equals
echo cA3IBIE3ymvliK9s6Xm9JUz3WGg= | base64 -d | hexdump -CSignature-Version: 1.0
Created-By: 1.0 (Android SignApk)
SHA1-Digest-Manifest: OkpBSsYl4MCoSfK/3jE4lXjluJ0=
Name: assets/data/audio/sfx/redbird_yell03.wav
SHA1-Digest: cA3IBIE3ymvliK9s6Xm9JUz3WGg=
Name: classes.dex
SHA1-Digest: t96vCMTEN4hD4eIPvfHAKEaQEAE=META-INF/CERT.RSA The .SF file is signed and the signature is placed in
the .RSA file. The .RSA file also contains, encoded inside it, the certificate
or certificate chain from the keystore which authenticates the public key
corresponding to the private key used for signing.
You can print out the certificates using the following lines of code:
openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text
keytool -printcert -file CERT.RSA
jarsigner -verify -certs -verbose out/production/PlatformHacking/PlatformHacking.apk
Listing platform keys on the other hand happens using openssl
openssl x509 -in platform.×509.pem -noout -text
I am assuming the following:
- A package is signed
- During install the signer is checked to grant permissions, after that dex
optimisation is performed - dexopt is performed
- When starting code that run in a package android checks the package crc32 and
timestamp agains the cache to determine if it is needed to dexopt again.
If not needed android assumes the data is “valid” no APK verification is
performed