Difference between a Signed and Unsigned Android apk

I had never looked into what "signing" an Android apk actually did.  It came up because I wanted to prepare an app for the Amazon app store, for which they want unsigned apps, and I wanted to use exactly the apk that underwent the automated tests.

Well, this is trivial but interesting.  The signed apk is simply the unsigned apk that has been signed via the JDK jarsigner tool. 

An Android apk is just a zip file, so to see the difference between a signed and unsigned apk built from Eclipse, you just need to unzip the files and compare the contents.  And the only difference should be that the signed apk will contain an extra folder "META-INF", which contains three files:

1) MANIFEST.MF - this lists each file in the archive, and the base64-encoded SHA1 hash of the contents of the file; for example, here's the entry for the Android project manifest:

Name: AndroidManifest.xml
SHA1-Digest: 2/Ek5ZsQE2qFvLZt2x4srQSSd7A=



2) CERT.SF - this is similar to the MANIFEST.MF file, except that instead of the SHA1 hash of the contents for a file, it lists a SHA1 hash of the lines for the file from the MANIFEST.MF file; here's the entry for the Android project manifest:

Name: AndroidManifest.xml
SHA1-Digest: 6ycpIZPMu943qFF8EDpPun7j4UQ=


where

"6ycpIZPMu943qFF8EDpPun7j4UQ="

is the SHA1 hash of this string from MANIFEST.MF

 "Name: AndroidManifest.xml
SHA1-Digest: 2/Ek5ZsQE2qFvLZt2x4srQSSd7A=
"

Note that the blank line after the digest line is included in the calculation of the SHA1 hash

3) CERT.RSA - this contains the signature of the CERT.SF file, as well as the certificate used for signing

So, to "unsign" an apk, all you need to do is remove the META-INF directory from the apk file itself, which can be done with zip tools

zip -d YourApp.apk META-INF/*

But in my case, just doing the diffs between the extracted contents of the signed and unsigned apks was enough to let me rest easier about submitting to Amazon the unsigned apk generated within Eclipse.  The specific command to do the diff was

diff -rq dir_where_unsigned_apk unzipped dir_where_signed_apk_unzipped

Popular Posts