拿某apk举例
用7z解压*.apk,可以看到如下目录
这里有三个重要的文件MANIFEST.MF、CERT.SF、CERT.RSA,它们的用途是对apk进行签名,我们今天就来分析三者之间的关系
1. MANIFEST.MF
MANIFEST.MF文件内容是
Manifest-Version: 1.0
Created-By: 1.0 (Android SignApk)
Name: META-INF/services/javax.ws.rs.ext.MessageBodyWriter
SHA-256-Digest: ****AaoOiGNRVH9r6iGb5fv0s2ODOAIT6dwnkv***fI=
Name: *
SHA-256-Digest: *
......
SHA-256-Digest的值是直接对该文件做sha256计算的结果。
2. CERT.SF
CERT.SF文件的内容是:
Signature-Version: 1.0
X-Android-APK-Signed: 2
SHA-256-Digest-Manifest: ****Ei3aTaMbAXMg7Rr304ocINfE6wy90Mlsxu***2Q=
Created-By: 1.0 (Android SignApk)
Name: META-INF/services/javax.ws.rs.ext.MessageBodyWriter
SHA-256-Digest: ****dbjojNgoyNv+KK8wLZARBNtHmq8y4XVtRQ***yk=
Name: *
SHA-256-Digest: *
......
CERT.SF文件的内容由来:
SHA-256-Digest:后面的内容是MANIFEST.MF对应行的连接前后共三行做摘要而来。
可以使用如下python代码
令test_str取值
test_str = 'Name: META-INF/services/javax.ws.rs.ext.MessageBodyWriter\r\nSHA-256-Digest: ****AaoOiGNRVH9r6iGb5fv0s2ODOAIT6dwnkv***fI=\r\n\r\n'
设置method
hash_method = "hash256_base64"
可以计算出结果。
hash256 base64 is ****dbjojNgoyNv+KK8wLZARBNtHmq8y4XVtRQ***yk=
3. CERT.RSA
CERT.RSA文件主要是证书,里面包括两个最重要的部分“publickey + signature”
3.1 publickey:
ERT.RSA更改后缀为.p7b,就可以打开查看公钥了。选择detail,点击copytofile后选择第二项“base64 encoded”,可以导出XX.cer的证书文件。这里看不到signature签名。
当然,也可以使用openssl工具,使用命令openssl x509 -in XX.cer -pubkey -noout > XX.pem 可以产生公钥的16进制字符串
ubuntu@ip-172-*-*-20:~/work$ openssl x509 -in pubkey.cer -pubkey -noout > pubkey.pem
ubuntu@ip-172-*-*-20:~/work$ cat pubkey.pem
-----BEGIN PUBLIC KEY-----
MIIB*********************************************
-----END PUBLIC KEY-----
3.2 signature:
经过二进制文件比对,同一个目录下两个apk证书相同,最后256bytes不同,很显然这是 RSA(2048)私钥加密后的签名,加密的什么呢?加密的是CERT.SF文件。
使用openssl命令openssl x509 -in XX.cer -pubkey -noout -text> XX.txt 可以得到整个证书的内容,最后的部分名为signature,实际上不同apk出现有相同的情况,不是真正的私钥签名内容。
Signature Algorithm: sha1WithRSAEncryption
6d:25:41:1b:e8:66:d2:99:c9:b8:04:06:0d:72:d5:c6:9d:0b:
*****************************************************
54:0f:17:92
若要获得真正签名内容可以使用openssl命令openssl asn1parse -inform der -in Last256Result.bin。
Last256Result.bin内容是证书二进制文件的最后256bit复制出来的。
经过与CERT.SF文件的哈希对比,是一样的,验证成功。
root@ip-172-**-*-20:~/work/cert$ openssl asn1parse -inform der -in Last256Result.bin
0:d=0 hl=2 l= 33 cons: SEQUENCE
2:d=1 hl=2 l= 9 cons: SEQUENCE
4:d=2 hl=2 l= 5 prim: OBJECT :sha1
11:d=2 hl=2 l= 0 prim: NULL
13:d=1 hl=2 l= 20 prim: OCTET STRING [HEX DUMP]:****8EB408606C641BB18C73DE0E23DC676D***9