声明:

1.本帖转载自:http://riusksk.blogbus.com/logs/272154406.html,仅供自用,勿喷

2.欢迎交流学习

签名后的APK,在/META-INF目录下会生成以下3个文件:

apk签名验证机制-LMLPHP

MANIFEST.MF:保存除META-INF文件以外其它各文件的SHA-1+base64编码后的值。

apk签名验证机制-LMLPHP

CERT.SF:在SHA1-Digest-Manifest中保存MANIFEST.MF文件的SHA-1+base64编码后的值,在后面的各项SHA1-Digest中保存MANIFEST.MF各子项内容SHA-1+Base64编码后的值

apk签名验证机制-LMLPHP

CERT.RSA/DSA/EC:保存用私钥计算出CERT.SF文件的数字签名、证书发布机构、有效期、公钥、所有者、签名算法等信息

apk签名验证机制-LMLPHP

Android应用签名验证过程中,满足以下条件才能安装应用:

1、SHA-1(除META-INF目录外的文件)  ==  MANIFEST.MF中的各SHA-1值;

2、(SHA-1 + Base64)(MANIFEST.MF文件及各子项) ==  CERT.SF中各值

3、公钥(CERT.SF) == CERT.RSA/DSA对SF文件的签名

Android 中关于签名验证相关源码分析:

关键源码主要位于:

http://code.metager.de/source/xref/android/4.4/frameworks/base/core/java/android/content/pm/PackageParser.java

http://code.metager.de/source/xref/android/4.4/libcore/luni/src/main/java/java/util/jar/JarVerifier.java

1、读取DSA/RSA/EC后缀的签名证书文件,然后调用verifyCertificate进行难,此处并无限制文件名,因此将CERT.RSA改成CERT123.RSA依然有效,但SF文件得跟RSA文件等签名证书文件同名:

apk签名验证机制-LMLPHP

2、读取SF(与后面证书同名)与RSA/DSA/EC文件的内容,再调用verifySignature进行校验:

apk签名验证机制-LMLPHP

3、在verifySignature进行校验时会去读取各项证书信息,包括证书序列号、拥有者、加密算法等等,然后判断CERT.RSA证书对CERT.SF的文件签名是否正确,防止CERT.SF被篡改,若成功则返回证书链,否则抛出异常:

apk签名验证机制-LMLPHP

4、在返回证书链时,对于自签名证书,则直接作为合法证书返回

apk签名验证机制-LMLPHP

5、继续回到verifyCertificate函数,它会校验SF文件中的MANIFEST.MF中各项Hash值是否正确,防止MF文件被篡改:

apk签名验证机制-LMLPHP

apk签名验证机制-LMLPHP

6、对于非系统应用,去枚举除META-INF目录以外的所有文件,然后进行哈希运算,并将其与MANIFEST.MF中的各文件哈希值进行比对,只有相匹配后才允许安装应用:

apk签名验证机制-LMLPHP

05-11 17:43