This is not a question about how to sign an .apk file. I want to know what does signing actually means and how it is implemented.
Inside the .apk file there is META-INF folder and inside that there are two files.
First one is CERT.SF contains SHA1 hashes for various components and looks like this:
Name: res/layout/main.xml SHA1-Digest: Cox/T8fN1X9Hv4VqjH9YKqc/MsM= Name: AndroidManifest.xml SHA1-Digest: wZ418H9Aix1LNch3ci7c+cHyuZc= Name: resources.arsc SHA1-Digest: P+uoRrpFyVW6P3Wf+4vuR2ZSuXY= Name: classes.dex SHA1-Digest: cN3zXtGii9zuTOkBqDTLymeMZQI=
There is also a file called CERT.RSA. I assume it is the public key to verify the signature.
My question is, where is the signature for the whole .apk file is stored? And what is actually signed? It could be either
- .apk file used as a single binary object and this is signed
- or CERT.SF is signed which contains individual hashes for different components
It would be also much better if you can point me to the documentation of the detailed signing and verification process.
This actually has nothing to do with Android. APK files are signed using
jarsigner. Here is a link to the manpage.
Indeed this is not a specific Android question but a Java-in-general question however I post an answer anyway…
First of all: Only the XXX.SF file is signed; this means that all the files mentioned in the XXX.SF file are signed “indirectly” because XXX.SF contains their hashes. In fact all files not located in “Meta-Inf” should have hashes there! The whole .apk archive is not signed.
The XXX.SF file is more or less a copy of the MANIFEST.MF file. There is a line “SHA1-Digest-Manifest” which is the SHA-1 hash of “MANIFEST.MF” itself; the “SHA1-Digest” lines do not contain the hashes of the files but the hashes of the tree corresponding lines in the Manifest.MF file just like this:
SHA1(“Name: filename”+CR+LF+”SHA1-Digest: “+SHA1(file_content)+CR+LF+CR+LF)
The file format of XXX.DSA/.RSA is the same as for an S/MIME email signature (for the content of XXX.SF) however the data is not base64 encoded and no header/trailer lines are used. “openssl smime -sign -outform DER” would create this format.
Multiple certificates can be used to sign a ZIP file. In this case multiple pairs of (XXX.SF/.RSA, YYY.SF/.RSA, …) will exist.