apk签名验证和数字签名原理

一、Android apk的签名文件

1.1、apk 签名文件

android apk解压之后有如下几个文件


image

其中META-INFO为签名文件夹,内部有三个文件:MANIFEST.MF、CERT.SF、CERT.RSA。其中:
MANIFEST.MF、CERT.SF 为apk内所有文件的一个摘要信息。
CERT.RSA 为签名和数字证书(公钥和辅助的身份信息)。

  • MANIFEST.MF:一级摘要文件,程序遍历Apk包中的所有文件(entry),对非文件夹非签名文件的文件,逐个用SHA1生成摘要信息,再用Base64进行编码。如果你改变了apk包中的文件,那么在apk安装校验时,改变后的文件摘要信息与MANIFEST.MF的检验信息不同,于是程序就不能成功安装。
MANIFEST.MF
  • CERT.SF:二级摘要文件:对前一步生成的MANIFEST.MF的每一条内容分别进行SHA1计算,然后再用Base64编码转换。同时把MANIFEST.MF的内容也进行SHA1计算,并且计算BASE64编码。

这是签名认证过程的第二步,这一步做的是对第一步得到的MANIFEST.MF提取了摘要,比如第一步中对文件和MANIFEST.MF摘要都改了,这一步中MANIFEST.MF的摘要值也要修改,否则就对应不起来。

[图片上传失败...(image-8eb227-1610693470559)]

前面这两步,做的都是摘要,是为第三步骤做准备的,第三步骤才是最重要的。

  • CERT.RSA 签名文件:最重要,里面保存了公钥、所采用的加密算法 和CERT.SF中的内容的用私钥进行加密之后的值(签名)

这一步中,即使开发者修改了程序内容,并生成了新的摘要文件,MANIFEST.MF能与内容对应起来,CERT.SF也能与内容对应起来,但是攻击者没有开发者的私钥,所以不能生成正确的签名文件(CERT.RSA)。
系统在对伪造的签名进行验证的时候,用CERT.RSA中的公钥,对CERT.RSA中的签名秘文进行解析,解出来的信息和CERT.SF中的摘要信息必然对不上,所以不能通过检验,也就不能成功安装文件。

签名和验证的过程可以用下图表示:

image

那有人会问,我把CERT.RSA中也修改了,把公钥和签名都替换了,重新生成一个CERT.RSA不就行了么?

这就涉及到另一个概念:数字证书。

前面提到CERT.RSA 为签名和数字证书(公钥和辅助的身份信息)组成。

  • 签名就是用私钥对摘要信息加密后的密文。
  • 数字证书是开发者身份的信息,其中最主要的是公钥,其次还有辅助身份信息。比如所有者,签发人,有效期等。

公钥代表了开发者主体身份的唯一性。公钥一样,开发者主体就是一个,公钥不一致肯定是不同的开发主体。

以微信为例,假设你手机上安装过微信,并且你修改微信apk中的个CERT.RSA,替换成了你自己的公钥,和你自己私钥加密后的签名。安装的时候,Android系统检测到,同一个包名,新apk的公钥和已安装的不一致,那么系统就会认为开发者主体不一致,要安装新的apk,需要先把就的apk卸载掉(系统认为公钥不一致,是两个不同的apk,但是两个不同的apk,包名不能一致,需要卸载其中一个)。

如果手机上原先没有安装过微信,此时安装修改了签名文件的apk,Android系统是可以校验通过,允许安装的。

那有同学又问了,数字证书中的辅助身份信息,如所有者,签发人,有效期等,这些辅助身份信息和公钥怎样建立一个可信任的匹配关系呢?毕竟我可以伪造数字证书,保留原有的辅助身份信息,用我自己的公钥替换掉原有的公钥信息,神不知鬼不觉。

数字证书的认证,这就涉及到数字证书结构和CA认证机构了。

彩蛋

查看CERT.RSA中的数字证书,可以用如下命令:

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

二、数字证书和CA认证

2.1、理论知识

涉及一些理论知识,在这里做一下回顾

对称加密

对称加密是指双方持有相同的密钥进行通信,加密速度快。但是有一个安全问题,双方怎样获得相同的密钥?你总不能总是拿着U盘把密钥拷贝给对方吧。
常见的对称加密算法有DES、3DES、AES等

非对称加密

非对称加密,又称为公开密钥加密,是为了解决对称加密中的安全问题而诞生,它的加密速度相对于对称加密来说很慢。

  • 公钥(public key)是对外开放的,私钥(private key)是自己拥有的。
  • 公钥(public key)加密的数据,只能用私钥(private key)解密。
  • 私钥(private key)加密的数据,只能用公钥(public key)解密。

信息安全问题

在信息安全性问题中,我们常常要做到三点才能保证信息的安全:

  • 信息的保密性
  • 信息的完整性
  • 身份识别

信息的保密性(加密算法)

信息的保密性我们可以使用对称加密和非对称加密配合来完成

信息的完整性(数字签名)

数字签名用来保证,信息传输的途中,没有被第三方劫持篡改。
通用方法是

  • 使用散列算法如SHA1,MD5将传输内容hash一次获得hash值,即摘要。
  • 采用私钥对摘要信息进行非对称加密,生成签名。将签名和公钥信息一起传递给对端。
  • 对端 采用公钥信息对签名进行解码,重新计算原始内容的hash值,如果与解密后的签名值一致,则说明信息未被篡改。

身份识别(数字证书)

在信息传输的过程中,我们通常需要验证信息的发送方的身份。这时我们转化一下思路,发送端把自己的内容通过私钥加密,然后把加密内容连同公钥一起发送给接收端,接收端只能用接收到的公钥解密,自然就验证了发送端的身份。 怎样保证发送端的公钥不被篡改(发送端的公钥可信任),这就需要数字证书技术了。

2.2、数字证书

数字证书代表服务端的身份,在传输的过程中是可以被篡改的。

服务器将数字证书(公钥和辅助身份信息)分发给客户端,如果一开始服务端发送的公钥到客户端的过程中有可能被第三方劫持,然后第三方自己伪造一对密钥,将公钥发送给客户端,当服务器发送数据给客户端的时候,中间人将信息进行劫持,用一开始劫持的公钥进行解密后,然后使用自己的私钥将数据加密发送给客户端,而客户端收到后使用公钥解密,反过来亦是如此,整个过程中间人是透明的,但信息泄露却不得而知。

image

2.2.1、CA认证

要解决数字证书(公钥)的可靠性,没有被篡改过,需要CA认证来帮助实现。

CA:Certificate Authority,颁发数字证书的机构,是负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。

CA中心为每个使用公开密钥的用户发放一个数字证书,数字证书的作用是证明证书中列出的用户合法拥有证书中列出的公开密钥。

2.2.2、数字证书结构

数据签名结构
数字证书=公钥+申请者与颁发者信息+签名;

数字证书又三部分组成:

  • 申请者公钥
  • 申请者与颁发者的信息 (身份辅助信息)
身份辅助信息:
申请者的组织信息和个人信息、签发机构 CA 的信息、有效时间、证书序列号等信息的明文
  • 证书颁发者提供的签名信息
签名的产生算法:

使用散列函数计算公开的明文信息(包括申请者公钥和申请者与办法这的信息)的信息摘要,采用 CA 的私钥对信息摘要进行加密,密文即签名。

数字证书合法性的验证

数字证书的颁发者是谁就应该找谁来验证。

数字证书的颁发机构一般是CA, 利用对应 CA 的公钥解密签名数据,然后读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,对比解密出的和新计算出的摘要信息是否一致。
如果一致,说明两点:

  • 此数字证书是CA 机构颁发的。
  • 此数字证书未被篡改过。
    因此数字证书是有效的,否则数字证书是无效的。
常见数字证书类型
X.509#DER 二进制格式证书,常用后缀.cer .crt
X.509#PEM 文本格式证书,常用后缀.pem
有的证书内容是只包含公钥(服务器的公钥),如.crt、.cer、.pem
有的证书既包含公钥又包含私钥(服务器的私钥),如.pfx、.p12
CA根证书

根证书是CA认证中心给自己颁发的证书,是信任链的起始点。安装根证书意味着对这个CA认证中心的信任。

一份数字证书 一定是有某一个签发机构授予的。该数字证书的信任,首先来源于对证书授予机构的信任。

验证一份证书的真伪(即验证CA中心对该证书信息的签名是否有效),需要用CA 中心的公钥验证,而CA中心的公钥存在于对这份证书进行签名的证书内,故需要下载该证书,但使用该证书验证又需先验证该证书本身的真伪,故又要用签发该证书的证书来验证,这样一来就构成一条证书链的关系,这条证书链的终点就是根证书。

根证书(CA 根证书)是一份特殊的证书,它的签发者是它本身,下载根证书就表明您对该根证书以下所签发的证书都表示信任,而技术上则是建立起一个验证证书信息的链条,证书的验证追溯至根证书即为结束。

三、参考文章

https://www.jianshu.com/p/29e0ba31fb8d

https://blog.csdn.net/xiqingnian/article/details/27338677

https://blog.csdn.net/hookfeng/article/details/38727091

你可能感兴趣的:(apk签名验证和数字签名原理)