Android签名概述
我们已经知道的是:Android对每一个Apk文件都会进行签名,在Apk文件安装时,系统会对其签名信息进行比对,判断程序的完整性,从而决定该Apk文件是否可以安装,在一定程度上达到安全的目的。
给定一个Apk文件,解压,可以看到一个META-INFO文件夹,在该文件夹下有三个文件:分别为MANIFEST.MF、CERT.SF和CERT.RSA。这三个文件分别表征以下含义:
MANIFEST.MF:
这是摘要文件。程序遍历Apk包中的所有文件(entry),对非文件夹非签名文件的文件,逐个用SHA1生成摘要信息,再用Base64进行编码。如果你改变了apk包中的文件,那么在apk安装校验时,改变后的文件摘要信息与MANIFEST.MF的检验信息不同,于是程序就不能成功安装。
说明:如果攻击者修改了程序的内容,有重新生成了新的摘要,那么就可以通过验证,所以这是一个非常简单的验证。
摘取部分内容:
Manifest-Version: 1.0
Built-By: Signflinger
Created-By: Android Gradle 4.2.2
Name: AndroidManifest.xml
SHA-256-Digest: gvhfCSLW84WS7dv5OeRij2UyCzAz04ux8NfH70rkvII=
Name: META-INF/androidx.activity_activity.version
SHA-256-Digest: FXXhr0qV8S9wtO5qatzoFglT2T6hfcJhG5CIPMw607g=
......
CERT.SF:
这是对摘要的签名文件。对前一步生成的MANIFEST.MF,使用SHA1-RSA算法,用开发者的私钥进行签名。在安装时只能使用公钥才能解密它。解密之后,将它与未加密的摘要信息(即,MANIFEST.MF文件)进行对比,如果相符,则表明内容没有被异常修改。
说明:在这一步,即使开发者修改了程序内容,并生成了新的摘要文件,但是攻击者没有开发者的私钥,所以不能生成正确的签名文件(CERT.SF)。系统在对程序进行验证的时候,用开发者公钥对不正确的签名文件进行解密,得到的结果和摘要文件(MANIFEST.MF)对应不起来,所以不能通过检验,不能成功安装文件。
例子:
Signature-Version: 1.0
Created-By: Android Gradle 4.2.2
SHA-256-Digest-Manifest: fwX795UOzz+QhReBetTLtfsEnjVOAMeEbWkTIJRtoUg=
X-Android-APK-Signed: 2
Name: AndroidManifest.xml
SHA-256-Digest: hXGX0k3MSRVEgUeveZGQRPwZht1TeWVKIIJL70L0lI4=
Name: META-INF/androidx.activity_activity.version
SHA-256-Digest: VB2/BAS6tzVHQlkRvGm43wcSdht5Ldk99tdvbvkq4zE=
......
CERT.RSA
文件中保存了公钥、所采用的加密算法等信息。 说明:系统对签名文件进行解密,所需要的公钥就是从这个文件里取出来的。
例子:
提取数据:
openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 15584183xx (0x5ce393b3)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=CN, ST=shanghai, L=shanghai, O=xx, OU=xx, CN=xx
Validity
Not Before: Sep 13 10:07:26 2018 GMT
Not After : Sep 7 10:07:26 2043 GMT
Subject: C=CN, ST=shanghai, L=shanghai, O=xx, OU=xx, CN=xx
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:af:82:29:ae:f9:32:2c:62:d7:5b:35:d1:ee:d8:
2d:1c:a5:90:f1:3f:a8:ca:7a:65:b2:85:92:c1:74:
0a:fa:47:eb:50:e0:d8:d9:a1:62:9c:ee:33:ae:56:
c6:7e:34:49:e9:81:92:bc:3a:da:6d:df:1b:3f:2e:
37:be:54:fa:10:91:ad:48:22:7f:3e:5f:55:97:44:
69:34:5e:2a:04:c5:87:86:15:5d:bc:2f:27:57:d4:
0d:0f:71:85:ea:1a:24:de:49:5c:29:ab:90:08:6e:
2d:e2:1c:be:54:40:80:2b:xx:71:e1:27:e9:8e:d3:
88:cf:6f:84:56:e6:cf:45:ff:78:81:93:e9:69:7a:
24:47:42:a7:19:a6:53:38:11:f0:f6:51:99:e6:db:
f2:29:25:f5:95:ef:89:38:xx:6e:21:67:56:bb:4e:
7f:df:23:9e:92:d6:00:c0:60:02:be:19:a7:ff:a0:
f9:84:80:63:97:82:25:52:52:a6:99:0f:1b:9e:11:
95:56:4b:34:2a:5c:e1:d9:4c:27:d8:1e:ff:78:74:
34:1b:1a:ff:de:7a:80:39:04:d1:1d:e7:b7:1e:da:
92:a9:53:4d:dc:3e:40:d7:f5:01:28:59:70:3a:a6:
ca:e9:99:a8:54:b0:33:4a:97:fe:cd:c4:bb:05:24:
c6:xx
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
41:77:D7:A5:E5:0B:3B:xx:C3:C0:2A:xx:33:CD:09:48:6C:DA:xx:xx
Signature Algorithm: sha256WithRSAEncryption
0f:16:9a:1c:8b:e6:66:1b:00:72:e8:cb:b2:4f:e0:32:91:e4:
e5:02:e4:84:2c:a9:23:10:f8:9c:83:81:9d:94:89:0d:47:a0:
e6:67:ed:77:f6:62:20:fe:01:ab:3b:8f:c1:73:b7:eb:43:96:
21:a9:14:d2:7d:xx:63:2e:0a:68:9f:00:ae:ae:9d:8b:d6:bd:
4b:6f:09:7b:50:01:ba:48:f0:17:a2:fd:fb:8a:cc:57:6f:cd:
9f:d8:dd:50:48:29:c7:xx:2b:64:89:e1:f5:8b:2b:69:8a:1a:
20:dc:de:4e:9f:cd:b4:92:18:3d:27:d8:07:2c:81:3e:92:da:
36:39:45:eb:78:db:ad:33:59:d2:a7:99:25:58:bb:a8:5c:9b:
66:0c:cb:4f:b7:ef:07:50:5c:56:79:13:06:ef:0b:d2:82:17:
8c:d9:e0:f7:85:75:6d:95:14:cb:a6:23:dc:4c:8b:9d:9a:b4:
8b:99:97:a7:a7:7e:af:9b:ce:61:49:ef:df:d0:90:7a:b8:45:
a0:46:80:cd:ea:08:6f:78:a8:c6:17:89:9d:ad:96:76:a6:16:
4f:86:10:b4:86:15:a1:dd:85:ae:da:ff:60:d6:ea:2e:38:8f:
bc:e3:0e:a5:64:b8:39:21:d6:90:89:50:34:91:9e:80:c7:08:
1f:bb:a3:xx