【Android安全】Android app开发者证书和代码签名机制

参考链接:

安卓证书相关验证机制:
https://duanqz.github.io/2017-09-01-Android-Digital-Signature
(部分内容不准确)

关于META-INF文件含义:
https://blog.csdn.net/diaoxuesong/article/details/78668659

关于V1 V2 V3签名机制:
https://zhuanlan.zhihu.com/p/108034286

数字证书原理:
https://network.51cto.com/article/628890.html

数字证书的结构:https://www.cnblogs.com/hyddd/archive/2009/01/07/1371292.html

关于CERT.RSA全部内容解析:
https://blog.csdn.net/diaoxuesong/article/details/78668659

安卓apk证书原理及实验验证

1. 数字签名

  • 对待发送的数据明文进行Hash,通常可采用MD5或SHA算法,然后采用私钥对Hash值进行加密,得到签名。将数据明文和签名一同发送出去。
    (为什么要先对原始数据进行Hash后再用私钥加密呢?因为原数据可能比较大,直接使用私钥加密将会非常耗时。)

  • 接收数据以后,会经过签名验证,其实就是比较两个Hash值:采用同样的Hash算法对数据明文进行哈希,得到一个Hash值;采用公钥对签名进行解密后,得到另一个Hash值。如果两个Hash值相同,则说明数据没有被篡改而且来源可信

2. keytool

keytool是JDK的一个工具,用于密钥和证书的管理。
keytool的主要操作对象是keystore文件,该文件一般以.keystore或.jks(Java KeyStore)为后缀名。
keystore可以存储多个密钥对(Key Pair),每一个密钥对包含私钥(Private Key)和多个证书(Certificate):
【Android安全】Android app开发者证书和代码签名机制_第1张图片

3. 证书(Certificate)

证书就是对公钥再次私钥签名产生的结果。证书中保存着被签名的公钥签名
【Android安全】Android app开发者证书和代码签名机制_第2张图片
【Android安全】Android app开发者证书和代码签名机制_第3张图片

3.1 证书认证机构CA(Certificate Authority)和证书链(Certificate Chain)

上述证书的生成过程会导致一个无限的链条:要得到证书,就需要对公钥A进行私钥B签名,并发布公钥B。这样就有两个公钥了:证书本身的公钥(即证书中的Public Key,用公钥A表示)和私钥B所对应的公钥(用公钥B表示)。

要保证公钥B的合法性,我们可以对公钥B再进行私钥C签名,这就又需要发布一个新的公钥C,…,公钥合法性的保证就像链条一样。要打破这个无限的链条,就需要有一个权威机构,来统一颁发证书,这个机构就是CA(Certificate Authority)。

CA的公钥被保存在OS中,被认为是可信的。

光靠一个CA是忙不过来的,CA得授权一些代理,这些代理也可以颁发证书,代理颁发的证书也被认为是合法可信的,这就形成了证书链。

keystore文件的结构:一个私钥(Private Key)与多个证书(Certificates)组成密钥对(Key Pair),其实多个证书的结构就是证书链

4. keystore

如果将keystore看做密钥和证书管理的数据库,那么keytool就是这个数据库增、删、改、查的接口。

5. Android V1签名方案

  • 应用层面:Android对APK的签名要求

    Android拒绝安装没有签名的APK
    Android并不校验证书的合法性(这与https网站证书不一样,https网站证书是要校验签发者的合法性的)
    当签名不匹配时,APK升级会失败

  • 系统层面:Android基于数字签名的一些机制
    编译Android系统时,会根据不同应用的类型进行签名
    Android基于数字签名来判定是否给应用授权
    Android基于数字签名来标记APK的SELinux Lable

6. META-INF目录

给定一个Apk文件,解压,可以看到一个META-INF文件夹,在该文件夹下有三个文件:分别为MANIFEST.MF、CERT.SF和CERT.RSA。

其中MANIFEST.MF名称基本固定,CERT.SF和CERT.RSA可能被换成其他名称(例如微信app中是COM_TENC.SF和COM_TENC.RSA)。


【Android安全】Android app开发者证书和代码签名机制_第4张图片

(实测一些APK中用的不是SHA-1,而是SHA-256)

也就是说,CERT.RSA中包含一个证书和一个签名,CERT.RSA并不是一个单纯的证书。

【Android安全】Android app开发者证书和代码签名机制_第5张图片

6.1 MANIFEST.MF文件

MANIFEST.MF:记录了APK中每一个文件的摘要

Manifest-Version: 1.0
Built-By: Generated-by-ADT
Created-By: Android Gradle 3.4.2

Name: AndroidManifest.xml
SHA-256-Digest: 4Gyn/1pQJm4vo9BPrcOhNA9dqX0xN+Ilux6qDn1f24I=

Name: META-INF/androidx.activity_activity.version
SHA-256-Digest: WYVJhIUxBN9cNT4vaBoV/HkkdC+aLkaMKa8kjc5FzgM=

Name: META-INF/androidx.annotation_annotation-experimental.version
SHA-256-Digest: WYVJhIUxBN9cNT4vaBoV/HkkdC+aLkaMKa8kjc5FzgM=

Name: META-INF/androidx.appcompat_appcompat-resources.version
SHA-256-Digest: HltRzeUVOWqfp2KQnPjKZYTMxWSzJdLuvup2F1/pXE0=

Name: META-INF/androidx.appcompat_appcompat.version
SHA-256-Digest: HltRzeUVOWqfp2KQnPjKZYTMxWSzJdLuvup2F1/pXE0=

Name: META-INF/androidx.arch.core_core-runtime.version
SHA-256-Digest: wo/MpTY3vIjhJK8XJd8Ty5jGne3v1i+zzb4c22t2BiQ=

…………

6.2 CERT.SF文件

CERT.SF:对MANIFEST.MF计算摘要,结果存放在SHA-256-Digest-Manifest;同时对MANIFEST.MF中每一项计算摘要,结果存放在CERT.SF各项中。

Signature-Version: 1.0
Created-By: 1.0 (Android)
SHA-256-Digest-Manifest: ifpWUlrHBqAXmGWiygrMlMr4BL+9Z+J1xzN6IAKIi7U=
X-Android-APK-Signed: 2

Name: AndroidManifest.xml
SHA-256-Digest: FM8SO8spjSfyYXZCcMfhl93XRKbKItHolj1eOAaLnx4=

Name: META-INF/androidx.activity_activity.version
SHA-256-Digest: Yu1eiqd7wti3kPabgLC0lsO+1ns/UAhiPGUExHOxH/w=

Name: META-INF/androidx.annotation_annotation-experimental.version
SHA-256-Digest: Lxz3EbTZKQ+6YHD56UXKdC4eR6Vt/RCS/mhbehwNKY0=

Name: META-INF/androidx.appcompat_appcompat-resources.version
SHA-256-Digest: d8qnGN0xpQnZXwhik1KeeAcyufb6b2l+Ods8bsHKkVE=

Name: META-INF/androidx.appcompat_appcompat.version
SHA-256-Digest: YwDR0Rxo15s+KFBZKd2nWg6Xm4mF+YmpBoHOItYOSoU=

Name: META-INF/androidx.arch.core_core-runtime.version
SHA-256-Digest: PjygIQMN5T6nIKT/hi5PFaxVcEB+W20fr4f0g2n7jrg=
…………

可以看出其中多出一项SHA-256-Digest-Manifest(值为ifpWUlrHBqAXmGWiygrMlMr4BL+9Z+J1xzN6IAKIi7U=)。这个是对MANIFEST.MF文件的SHA256值经Base64编码得到的。

验证过程如下:

利用在线工具(该工具可离线保存),计算MANIFEST.MF文件的SHA256值:89fa56525ac706a0179865a2ca0acc94caf804bfbd67e275c7337a2002888bb5
【Android安全】Android app开发者证书和代码签名机制_第6张图片

利用在线工具,求出SHA256值(16进制形式)的Base64编码结果:ifpWUlrHBqAXmGWiygrMlMr4BL+9Z+J1xzN6IAKIi7U=
【Android安全】Android app开发者证书和代码签名机制_第7张图片
该值与CERT.SF中的SHA-256-Digest-Manifest相同。

6.3 CERT.RSA文件

CERT.RSA:主要内容是对CERT.SF的私钥A签名(对CERT.SF的摘要的私钥A加密) 和 证书(用于保存公钥A) 。RSA后缀表示签名是基于RSA算法生成的。

证书的本质作用是保存公钥A。同时,证书具备可验证性(在某些额外信息被获取的情况下,用户可以判定证书是否是合法的)。

注意,CERT.RSA是三者中唯一用到私钥的。


6.3.1 证书部分分析

证书保存了:{公钥A+相关信息}{公钥A+相关信息}的私钥B签名结果(和签名算法)。公钥A和私钥A是一对,公钥B和私钥B是一对。当需要验证证书的合法性时,用户从某些途径获取到公钥B(通常是通过上一级证书),而后对 {公钥A+相关信息}的私钥B签名结果 进行解密,得到摘要1;对 {公钥A+相关信息} 计算摘要,得到摘要2;比较摘要1和摘要2是否相同。若相同,则说明证书是可信的。

使用Openssl可以提取其中证书部分内容:

openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text > CERT.RSA-cert.txt

内容如下:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 33548542 (0x1ffe8fe)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN
        Validity
            Not Before: Dec 20 04:41:56 2018 GMT
            Not After : Dec 14 04:41:56 2043 GMT
        Subject: C=CN
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:dd:3f:31:51:7f:b3:2f:dd:07:9c:6f:66:3d:eb:
                    17:84:6d:7a:19:1f:bd:63:07:e3:be:30:41:09:a3:
                    84:e7:ab:7f:4b:88:0c:b6:27:3d:38:e6:28:3b:60:
                    ac:19:a9:98:cd:0f:3c:24:67:47:5f:f8:11:b1:e6:
                    00:eb:b0:a4:97:ff:db:db:1f:f8:e8:f7:74:66:51:
                    e2:46:7a:8b:ea:99:28:72:6e:83:f2:d3:50:0c:7e:
                    aa:e5:8a:58:03:98:e9:04:cd:1f:55:39:64:88:b8:
                    92:99:7c:ec:3f:a3:b8:68:44:df:f0:70:b1:2c:50:
                    d6:e8:be:82:3b:20:b6:04:cd:37:e1:1a:43:9b:7e:
                    b5:64:86:8e:ab:8f:8a:c1:86:7d:d8:cb:c7:a3:0c:
                    38:75:01:f4:ec:ad:ec:f5:5c:22:33:80:d6:d9:40:
                    69:dc:f2:d0:7d:19:69:8b:69:f8:48:b3:6f:b0:3c:
                    83:95:17:6d:5b:21:34:64:61:4a:f8:f3:80:fe:e7:
                    f3:2e:7b:86:4a:c8:f7:e2:e0:cd:ff:4f:e3:ad:d9:
                    18:58:fb:cc:7e:29:ff:a1:b8:20:37:25:31:cb:c1:
                    08:84:a2:07:08:35:4f:c9:52:28:c4:56:6a:59:92:
                    bd:ea:3d:47:41:80:1b:a5:0d:f1:f9:52:27:54:63:
                    d4:2f
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                07:8C:E8:A0:26:83:A6:E8:5D:C1:84:E7:C2:D4:45:8E:A4:D8:62:5A
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        3c:0c:03:7f:5c:20:92:0d:f1:a7:9a:35:77:23:b9:f2:d4:bc:
        76:81:f6:2a:4b:6e:ac:7b:e7:e1:b4:c2:5b:e2:56:b5:cb:33:
        c4:d6:5e:12:64:df:5a:a6:0c:3d:e6:74:e8:2b:62:3f:7f:0a:
        16:51:51:ce:9c:f2:c1:88:6c:71:2b:73:53:0a:09:1c:60:86:
        5d:6f:94:9e:60:0d:dd:a8:f6:e6:51:bf:13:d7:d9:38:81:ea:
        4b:88:87:20:b0:bf:23:93:3c:9b:85:43:f8:81:f8:e2:ee:0d:
        24:6b:48:c9:0b:e7:3c:eb:2d:a9:68:04:aa:44:6c:b0:59:80:
        2b:3c:7e:ba:70:35:b5:22:32:d7:bf:3f:5b:7b:fb:bb:bf:ae:
        b0:78:8e:4e:5a:87:2c:1a:b9:8f:1b:f9:1b:01:15:b5:fb:9a:
        51:53:f6:a2:8b:93:84:37:f5:93:b9:f3:06:4d:37:10:21:f8:
        e0:c8:83:1e:a4:f1:75:64:41:59:1b:68:c2:26:e3:9b:c0:8c:
        d1:61:6c:62:bb:5b:fc:8f:d4:ee:e5:c2:97:6d:7a:e0:01:b9:
        7c:08:7e:10:59:f6:4b:d7:7a:9f:c1:d6:99:c7:dd:89:ff:a2:
        1c:13:53:b2:5f:09:5a:82:1d:b4:bf:59:63:bb:66:a6:88:0a:
        4b:a2:f4:47

【Android安全】Android app开发者证书和代码签名机制_第8张图片
【Android安全】Android app开发者证书和代码签名机制_第9张图片

其中:

Signature Value( 3C 0C 03 7F …… 47)是 {公钥A+相关信息}的私钥B签名结果,用于验证证书的可信性,这里暂时不涉及

使用JEB也可以查看Signature Value:
【Android安全】Android app开发者证书和代码签名机制_第10张图片

Modulus(模数)和Exponent(指数)共同构成公钥。
Modulus 为:

DD3F31517FB32FDD079C6F663DEB17846D7A191FBD6307E3BE304109A384E7AB7F4B880CB6273D38E6283B60AC19A998CD0F3C2467475FF811B1E600EBB0A497FFDBDB1FF8E8F7746651E2467A8BEA9928726E83F2D3500C7EAAE58A580398E904CD1F55396488B892997CEC3FA3B86844DFF070B12C50D6E8BE823B20B604CD37E11A439B7EB564868EAB8F8AC1867DD8CBC7A30C387501F4ECADECF55C223380D6D94069DCF2D07D19698B69F848B36FB03C8395176D5B213464614AF8F380FEE7F32E7B864AC8F7E2E0CDFF4FE3ADD91858FBCC7E29FFA1B820372531CBC10884A20708354FC95228C4566A5992BDEA3D4741801BA50DF1F952275463D42F

Exponent 为:65537 (0x10001)

通过在线工具生成PEM格式的RSA公钥:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3T8xUX+zL90HnG9mPesX
hG16GR+9YwfjvjBBCaOE56t/S4gMtic9OOYoO2CsGamYzQ88JGdHX/gRseYA67Ck
l//b2x/46Pd0ZlHiRnqL6pkocm6D8tNQDH6q5YpYA5jpBM0fVTlkiLiSmXzsP6O4
aETf8HCxLFDW6L6COyC2BM034RpDm361ZIaOq4+KwYZ92MvHoww4dQH07K3s9Vwi
M4DW2UBp3PLQfRlpi2n4SLNvsDyDlRdtWyE0ZGFK+POA/ufzLnuGSsj34uDN/0/j
rdkYWPvMfin/obggNyUxy8EIhKIHCDVPyVIoxFZqWZK96j1HQYAbpQ3x+VInVGPU
LwIDAQAB
-----END PUBLIC KEY-----

6.3.2 对CERT.SF的私钥A签名部分分析

使用Openssl查看CERT.RSA中全部内容:

openssl asn1parse -inform DER -in CERT.RSA -dump > CERT.RSA.txt
    0:d=0  hl=4 l=1081 cons: SEQUENCE          
    4:d=1  hl=2 l=   9 prim: OBJECT            :pkcs7-signedData
   15:d=1  hl=4 l=1066 cons: cont [ 0 ]        
   19:d=2  hl=4 l=1062 cons: SEQUENCE          
   23:d=3  hl=2 l=   1 prim: INTEGER           :01
   26:d=3  hl=2 l=  15 cons: SET               
   28:d=4  hl=2 l=  13 cons: SEQUENCE          
   30:d=5  hl=2 l=   9 prim: OBJECT            :sha256
   41:d=5  hl=2 l=   0 prim: NULL              
   43:d=3  hl=2 l=  11 cons: SEQUENCE          
   45:d=4  hl=2 l=   9 prim: OBJECT            :pkcs7-data
   56:d=3  hl=4 l= 701 cons: cont [ 0 ]        
   60:d=4  hl=4 l= 697 cons: SEQUENCE          
   64:d=5  hl=4 l= 417 cons: SEQUENCE          
   68:d=6  hl=2 l=   3 cons: cont [ 0 ]        
   70:d=7  hl=2 l=   1 prim: INTEGER           :02
   73:d=6  hl=2 l=   4 prim: INTEGER           :01FFE8FE
   79:d=6  hl=2 l=  13 cons: SEQUENCE          
   81:d=7  hl=2 l=   9 prim: OBJECT            :sha256WithRSAEncryption
   92:d=7  hl=2 l=   0 prim: NULL              
   94:d=6  hl=2 l=  13 cons: SEQUENCE          
   96:d=7  hl=2 l=  11 cons: SET               
   98:d=8  hl=2 l=   9 cons: SEQUENCE          
  100:d=9  hl=2 l=   3 prim: OBJECT            :countryName
  105:d=9  hl=2 l=   2 prim: PRINTABLESTRING   :CN
  109:d=6  hl=2 l=  30 cons: SEQUENCE          
  111:d=7  hl=2 l=  13 prim: UTCTIME           :181220044156Z
  126:d=7  hl=2 l=  13 prim: UTCTIME           :431214044156Z
  141:d=6  hl=2 l=  13 cons: SEQUENCE          
  143:d=7  hl=2 l=  11 cons: SET               
  145:d=8  hl=2 l=   9 cons: SEQUENCE          
  147:d=9  hl=2 l=   3 prim: OBJECT            :countryName
  152:d=9  hl=2 l=   2 prim: PRINTABLESTRING   :CN
  156:d=6  hl=4 l= 290 cons: SEQUENCE          
  160:d=7  hl=2 l=  13 cons: SEQUENCE          
  162:d=8  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  173:d=8  hl=2 l=   0 prim: NULL              
  175:d=7  hl=4 l= 271 prim: BIT STRING        
      0000 - 00 30 82 01 0a 02 82 01-01 00 dd 3f 31 51 7f b3   .0.........?1Q..
      0010 - 2f dd 07 9c 6f 66 3d eb-17 84 6d 7a 19 1f bd 63   /...of=...mz...c
      0020 - 07 e3 be 30 41 09 a3 84-e7 ab 7f 4b 88 0c b6 27   ...0A......K...'
      0030 - 3d 38 e6 28 3b 60 ac 19-a9 98 cd 0f 3c 24 67 47   =8.(;`......<$gG
      0040 - 5f f8 11 b1 e6 00 eb b0-a4 97 ff db db 1f f8 e8   _...............
      0050 - f7 74 66 51 e2 46 7a 8b-ea 99 28 72 6e 83 f2 d3   .tfQ.Fz...(rn...
      0060 - 50 0c 7e aa e5 8a 58 03-98 e9 04 cd 1f 55 39 64   P.~...X......U9d
      0070 - 88 b8 92 99 7c ec 3f a3-b8 68 44 df f0 70 b1 2c   ....|.?..hD..p.,
      0080 - 50 d6 e8 be 82 3b 20 b6-04 cd 37 e1 1a 43 9b 7e   P....; ...7..C.~
      0090 - b5 64 86 8e ab 8f 8a c1-86 7d d8 cb c7 a3 0c 38   .d.......}.....8
      00a0 - 75 01 f4 ec ad ec f5 5c-22 33 80 d6 d9 40 69 dc   u......\"3...@i.
      00b0 - f2 d0 7d 19 69 8b 69 f8-48 b3 6f b0 3c 83 95 17   ..}.i.i.H.o.<...
      00c0 - 6d 5b 21 34 64 61 4a f8-f3 80 fe e7 f3 2e 7b 86   m[!4daJ.......{.
      00d0 - 4a c8 f7 e2 e0 cd ff 4f-e3 ad d9 18 58 fb cc 7e   J......O....X..~
      00e0 - 29 ff a1 b8 20 37 25 31-cb c1 08 84 a2 07 08 35   )... 7%1.......5
      00f0 - 4f c9 52 28 c4 56 6a 59-92 bd ea 3d 47 41 80 1b   O.R(.VjY...=GA..
      0100 - a5 0d f1 f9 52 27 54 63-d4 2f 02 03 01 00 01      ....R'Tc./.....
  450:d=6  hl=2 l=  33 cons: cont [ 3 ]        
  452:d=7  hl=2 l=  31 cons: SEQUENCE          
  454:d=8  hl=2 l=  29 cons: SEQUENCE          
  456:d=9  hl=2 l=   3 prim: OBJECT            :X509v3 Subject Key Identifier
  461:d=9  hl=2 l=  22 prim: OCTET STRING      
      0000 - 04 14 07 8c e8 a0 26 83-a6 e8 5d c1 84 e7 c2 d4   ......&...].....
      0010 - 45 8e a4 d8 62 5a                                 E...bZ
  485:d=5  hl=2 l=  13 cons: SEQUENCE          
  487:d=6  hl=2 l=   9 prim: OBJECT            :sha256WithRSAEncryption
  498:d=6  hl=2 l=   0 prim: NULL              
  500:d=5  hl=4 l= 257 prim: BIT STRING        
      0000 - 00 3c 0c 03 7f 5c 20 92-0d f1 a7 9a 35 77 23 b9   .<...\ .....5w#.
      0010 - f2 d4 bc 76 81 f6 2a 4b-6e ac 7b e7 e1 b4 c2 5b   ...v..*Kn.{....[
      0020 - e2 56 b5 cb 33 c4 d6 5e-12 64 df 5a a6 0c 3d e6   .V..3..^.d.Z..=.
      0030 - 74 e8 2b 62 3f 7f 0a 16-51 51 ce 9c f2 c1 88 6c   t.+b?...QQ.....l
      0040 - 71 2b 73 53 0a 09 1c 60-86 5d 6f 94 9e 60 0d dd   q+sS...`.]o..`..
      0050 - a8 f6 e6 51 bf 13 d7 d9-38 81 ea 4b 88 87 20 b0   ...Q....8..K.. .
      0060 - bf 23 93 3c 9b 85 43 f8-81 f8 e2 ee 0d 24 6b 48   .#.<..C......$kH
      0070 - c9 0b e7 3c eb 2d a9 68-04 aa 44 6c b0 59 80 2b   ...<.-.h..Dl.Y.+
      0080 - 3c 7e ba 70 35 b5 22 32-d7 bf 3f 5b 7b fb bb bf   <~.p5."2..?[{...
      0090 - ae b0 78 8e 4e 5a 87 2c-1a b9 8f 1b f9 1b 01 15   ..x.NZ.,........
      00a0 - b5 fb 9a 51 53 f6 a2 8b-93 84 37 f5 93 b9 f3 06   ...QS.....7.....
      00b0 - 4d 37 10 21 f8 e0 c8 83-1e a4 f1 75 64 41 59 1b   M7.!.......udAY.
      00c0 - 68 c2 26 e3 9b c0 8c d1-61 6c 62 bb 5b fc 8f d4   h.&.....alb.[...
      00d0 - ee e5 c2 97 6d 7a e0 01-b9 7c 08 7e 10 59 f6 4b   ....mz...|.~.Y.K
      00e0 - d7 7a 9f c1 d6 99 c7 dd-89 ff a2 1c 13 53 b2 5f   .z...........S._
      00f0 - 09 5a 82 1d b4 bf 59 63-bb 66 a6 88 0a 4b a2 f4   .Z....Yc.f...K..
      0100 - 47                                                G
  761:d=3  hl=4 l= 320 cons: SET               
  765:d=4  hl=4 l= 316 cons: SEQUENCE          
  769:d=5  hl=2 l=   1 prim: INTEGER           :01
  772:d=5  hl=2 l=  21 cons: SEQUENCE          
  774:d=6  hl=2 l=  13 cons: SEQUENCE          
  776:d=7  hl=2 l=  11 cons: SET               
  778:d=8  hl=2 l=   9 cons: SEQUENCE          
  780:d=9  hl=2 l=   3 prim: OBJECT            :countryName
  785:d=9  hl=2 l=   2 prim: PRINTABLESTRING   :CN
  789:d=6  hl=2 l=   4 prim: INTEGER           :01FFE8FE
  795:d=5  hl=2 l=  13 cons: SEQUENCE          
  797:d=6  hl=2 l=   9 prim: OBJECT            :sha256
  808:d=6  hl=2 l=   0 prim: NULL              
  810:d=5  hl=2 l=  13 cons: SEQUENCE          
  812:d=6  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  823:d=6  hl=2 l=   0 prim: NULL              
  825:d=5  hl=4 l= 256 prim: OCTET STRING      
      0000 - 13 6e 93 d0 23 ce b7 33-d5 ed fa e7 cd 10 cf 56   .n..#..3.......V
      0010 - 77 c5 e5 f6 03 07 49 31-70 d3 ad 1f 01 69 e0 e7   w.....I1p....i..
      0020 - 31 0b 9b 26 57 7a e0 b1-66 79 79 8e af 57 ac 44   1..&Wz..fyy..W.D
      0030 - c5 88 d5 50 cd ba 5e f9-0e e9 77 17 30 50 29 28   ...P..^...w.0P)(
      0040 - 08 aa 98 20 3b 56 2f f6-10 2e e4 d8 2b 29 e4 6e   ... ;V/.....+).n
      0050 - 9d 4e 96 e2 03 0c df af-9a b4 bb fd a8 9c f7 39   .N.............9
      0060 - 29 45 23 3f 01 13 0e 3d-b7 02 a2 d8 53 6a eb aa   )E#?...=....Sj..
      0070 - 21 71 9a af 0f 35 5b ec-26 51 d0 22 96 df 8d 14   !q...5[.&Q."....
      0080 - 88 98 d4 d4 de 29 9d 77-17 96 e2 e3 bd cc b7 f0   .....).w........
      0090 - 61 17 48 a8 33 f5 2e 40-77 b2 42 e1 cf db ef ac   [email protected].....
      00a0 - 65 a2 1e 10 2e a2 47 8f-b6 9b 7b 3b 84 43 bd 92   e.....G...{;.C..
      00b0 - 57 72 ca e5 f8 d9 72 7d-3c 11 d7 4b b9 b0 1f ca   Wr....r}<..K....
      00c0 - 23 e3 07 bb d0 60 4d 4c-0c 28 11 bd 79 8a 2e b8   #....`ML.(..y...
      00d0 - ce 75 6c bb 53 15 36 79-25 39 6c 55 66 97 87 5a   .ul.S.6y%9lUf..Z
      00e0 - be 8e ad 29 cc 99 f9 fa-c0 c7 fe 9d 7b f9 47 22   ...)........{.G"
      00f0 - da ad 6d 90 66 61 52 45-95 cf 15 18 3c f3 51 58   ..m.faRE....<.QX

其中00 3c 0c ... 47是对证书加密的结果,用于验证证书的可信性,这里不涉及。

末尾的16进制数13 6e ... 58对CERT.SF的私钥A签名,也就是:

136E93D023CEB733D5EDFAE7CD10CF5677C5E5F60307493170D3AD1F0169E0E7310B9B26577AE0B16679798EAF57AC44C588D550CDBA5EF90EE977173050292808AA98203B562FF6102EE4D82B29E46E9D4E96E2030CDFAF9AB4BBFDA89CF7392945233F01130E3DB702A2D8536AEBAA21719AAF0F355BEC2651D02296DF8D148898D4D4DE299D771796E2E3BDCCB7F0611748A833F52E4077B242E1CFDBEFAC65A21E102EA2478FB69B7B3B8443BD925772CAE5F8D9727D3C11D74BB9B01FCA23E307BBD0604D4C0C2811BD798A2EB8CE756CBB5315367925396C556697875ABE8EAD29CC99F9FAC0C7FE9D7BF94722DAAD6D906661524595CF15183CF35158

使用在线工具对该值进行解密。
其中,公钥是PEM格式的,由前文提到的Modulus和Exponent生成,如下:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3T8xUX+zL90HnG9mPesX
hG16GR+9YwfjvjBBCaOE56t/S4gMtic9OOYoO2CsGamYzQ88JGdHX/gRseYA67Ck
l//b2x/46Pd0ZlHiRnqL6pkocm6D8tNQDH6q5YpYA5jpBM0fVTlkiLiSmXzsP6O4
aETf8HCxLFDW6L6COyC2BM034RpDm361ZIaOq4+KwYZ92MvHoww4dQH07K3s9Vwi
M4DW2UBp3PLQfRlpi2n4SLNvsDyDlRdtWyE0ZGFK+POA/ufzLnuGSsj34uDN/0/j
rdkYWPvMfin/obggNyUxy8EIhKIHCDVPyVIoxFZqWZK96j1HQYAbpQ3x+VInVGPU
LwIDAQAB
-----END PUBLIC KEY-----

解密结果:
【Android安全】Android app开发者证书和代码签名机制_第11张图片
解密得到的数据为:

30 31 30 0D 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 A2 B4 DB 1A 50 BE BC 75 40 5B AB E5 C1 3B 96 CF DF 92 E6 50 65 4E DB 6F 56 46 E0 2B 41 B2 C1 E9

其中的A2 B4 DB 1A 50 BE BC 75 40 5B AB E5 C1 3B 96 CF DF 92 E6 50 65 4E DB 6F 56 46 E0 2B 41 B2 C1 E9就是CERT.SF的SHA256摘要

验证如下:
【Android安全】Android app开发者证书和代码签名机制_第12张图片


6.3.3 从CERT.RSA中提取证书指纹(Fingerprint)

证书指纹是对证书的哈希值。

使用keytool也可以查看CERT.RSA中的证书指纹:

keytool --printcert -file CERT.RSA
所有者: C=CN
发布者: C=CN
序列号: 1ffe8fe
生效时间: Thu Dec 20 12:41:56 CST 2018, 失效时间: Mon Dec 14 12:41:56 CST 2043
证书指纹:
         SHA1: 8B:4F:1A:B3:95:AB:B7:49:1F:44:49:E5:51:00:06:8A:FA:53:39:8B
         SHA256: 8A:73:D3:A5:73:B4:30:18:81:ED:60:2A:57:6A:2C:BF:50:07:8C:4C:C8:0B:CE:52:FF:F7:19:33:98:6B:7A:66
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3

扩展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 07 8C E8 A0 26 83 A6 E8   5D C1 84 E7 C2 D4 45 8E  ....&...].....E.
0010: A4 D8 62 5A                                        ..bZ
]
]

使用JEB也可以查看相关信息:
【Android安全】Android app开发者证书和代码签名机制_第13张图片
该Fingerprint常用于各种第三方SDK平台的客户端身份验证(要求将该值上报到SDK平台,SDK中调接口获取)。

6.3.4 APP如何获得证书指纹(Fingerprint)

app通常需要获取证书指纹,以验证当前的app客户端是否被tampered了。

app中相关的java代码如下:

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) 
    {
        packageInfo = packageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNING_CERTIFICATES);
        SigningInfo signingInfo = packageInfo.signingInfo;
        signatures = signingInfo.getApkContentsSigners();
    } else {
        packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
        signatures = packageInfo.signatures;
    }
    String signBase64 = Base64Util.encodeToString(signatures [0].toByteArray());
    nowSignMD5 = MD5Utils.MD5(signBase64);

7. 相关校验

7.1 App层面

7.1.1 Android拒绝安装没有证书的APK

通过命令行adb install安装一个没有签名的APK时,会提示INSTALL_PARSE_FAILED_NO_CERTIFICATES错误。

7.1.2 Android不校验证书的合法性

只要证书中公钥解密CERT.SF签名得到的CERT.SF摘要,和计算出的CERT.SF摘要相同,不管证书是不是合法的,Android都允许安装。

7.1.3 两个版本证书不一致时,APK升级失败

如果一个APK的前后两个版本证书不一致时,Android拒绝升级APK。

7.2 操作系统层面

7.2.1 Android中的系统签名

Android设计了四种不同类型的签名:platform, share, media和testkey,默认置于在源码的build/target/product/security目录下,分别用于给不同类型的系统应用进行签名。从Android Lollipop开始,Android还对boot.img和system.img进行签名以防被篡改,所以在原来四组签名的基础上又增加了verity。

build/target/product/security
├── (media.pk8, media.x509.pem)       #用于给MediaProvider, Gallery等签名
├── (platform.pk8, platform.x509.pem) #用于给Settings, Phone等签名
├── (shared.pk8, shared.x509.pem)     #用于给Launcher, Dailer等签名
├── (testkey.pk8, testkey.x509.pem)   #用于给一般应用签名
└── (verity.pk8, verity.x509.pem)     #用于给boot.img和system.img签名

.pk8为私钥, .509.pem为证书(包含公钥)。

7.2.2 根据签名界定权限

应用可以定义属于自己的permission,并为其设定protectionLevel,通过Android的权限授予机制,来防止API被滥用。
譬如在packages/apps/Launcer3/AndroidManifest.xml中,就定义了如下权限:

<permission
    android:name="com.android.launcher3.permission.WRITE_SETTINGS"
    android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
    android:protectionLevel="signatureOrSystem"
    android:label="@string/permlab_write_settings"
    android:description="@string/permdesc_write_settings"/>

注意android:protectionLevel="signatureOrSystem"
这就表明一个app要想获取com.android.launcher3.permission.WRITE_SETTINGS这个权限,app要么与Launcher3具有相同的签名(公私钥对),要么是一个系统应用。

有了数字签名,就相当于多了一种受信机制。两个不同的APK,签名相同,意味着来源相同,彼此是受信的。

7.2.3 SELinux根据签名给APK打标签

详细内容参考《Android数字签名机制和应用场景》

在SELinux环境下,所有的文件和进程都有标签(文件通过ls -Z命令,进程通过ps -Z命令可以查看),这个标签称为SELinux Context

  • 部分标签是事先定义好的,譬如system/sepolicy/file_contexts文件中定义了一些系统文件和目录的标签;
  • 部分标签是根据规则生成的,譬如在fork子进程时,会根据TE(Type Enforcement)文件中定义的规则,为子进程打上标签。
    在这里插入图片描述
  1. Android基于签名为APK打标签。system/sepolicy/mac_permissions.xml中记录签名到SELinux标签的映射
  2. 当APK的应用进程启动时,根据seapp_contexts中定义的seinfo=>SELinux Context映射,设置进程的SELinux标签。

不同的标签对应着不同的可操作文件类型(例如system_app_data_file等)。

你可能感兴趣的:(安卓安全,android,安全)