签名技术
一、背景知识
1. 数字摘要
数字摘要是将任意长度的消息变成固定长度的短消息,它类似于一个自变量是消息的函数,也就是Hash函数。数字摘要就是采用单向Hash函数将需要加密的明文“摘要”成一串固定长度(128位)的密文这一串密文又称为数字指纹,它有固定的长度,而且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。
一个Hash函数的好坏是由发生碰撞的概率决定的。如果攻击者能够轻易地构造出两个消息具有相同的Hash值,那么这样的Hash函数是很危险的。一般来说,安全Hash标准的输出长度为160位,这样才能保证它足够的安全。 这一加密方法亦称安全Hash编码法(SHA:Secure Hash Algorithm)或MD5(MD Standards for Message Digest),由Ron Rivest所设计。该编码法采用单向Hash函数将需加密的明文“摘要”成一串128bit的密文,这一串密文亦称为数字指纹(Finger Print),它有固定的长度,且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。这样这摘要便可成为验证明文是否是“真身”的“指纹”了。
(摘自百度百科)
2. 数字签名
数字签名(又称公钥数字签名、电子签章)是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。
数字签名,就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。
数字签名是非对称密钥加密技术与数字摘要技术的应用。
一般来说,非对称加密是用来处理短消息的,而相对于较长的消息则显得有些吃力。当然,可以将长的消息分成若干小段,然后再分别签名。不过,这样做非常麻烦,而且会带来数据完整性的问题。比较合理的做法是在数字签名前对消息先进行数字摘要。
签名过程:
“发送报文时,发送方用一个哈希函数从报文文本中生成报文摘要,然后用自己的私人密钥对这个摘要进行加密,这个加密后的摘要将作为报文的数字签名和报文一起发送给接收方,接收方首先用与发送方一样的哈希函数从接收到的原始报文中计算出报文摘要,接着再用发送方的公用密钥来对报文附加的数字签名进行解密,如果这两个摘要相同、那么接收方就能确认该数字签名是发送方的。
数字签名有两种功效:一是能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名。二是数字签名能确定消息的完整性。因为数字签名的特点是它代表了文件的特征,文件如果发生改变,数字摘要的值也将发生变化。不同的文件将得到不同的数字摘要。 一次数字签名涉及到一个哈希函数、发送者的公钥、发送者的私钥。”
数字签名:
发送方用自己的密钥对报文X进行Encrypt(编码)运算,生成不可读取的密文Dsk,然后将Dsk传送给接收方,接收方为了核实签名,用发送方的公用密钥进行Decrypt(解码)运算,还原报文。
数字签名工作原理图
![](https://img.haomeiwen.com/i4055449/74e2e50190175578.png)
(摘自百度百科)
二、 Android 应用签名过程
三、 Android 应用签名验证过程
四、Others
APK签名方案:
4.1 方案1-基于JAR签名的方案
从一开始,APK 签名就是 Android 的一个有机部分。该方案基于签名的 JAR。如要详细了解如何使用该方案,请参阅介绍如何为您的应用签名的 Android Studio 文档。
v1 签名不保护 APK 的某些部分,例如 ZIP 元数据。APK 验证程序需要处理大量不可信(尚未经过验证)的数据结构,然后会舍弃不受签名保护的数据。这会导致相当大的受攻击面。此外,APK 验证程序必须解压所有已压缩的条目,而这需要花费更多时间和内存。为了解决这些问题,Android 7.0 中引入了 APK 签名方案 v2。
4.2 方案2-基于Apk的签名方案
Android 7.0 中引入了 APK 签名方案 v2(v2 方案)。该方案会对 APK 的内容进行哈希处理和签名,然后将生成的“APK 签名分块”插入到 APK 中。如要详细了解如何在应用中使用 v2 方案,请参阅 Android N 开发者预览版中的 APK 签名方案 v2。
在验证期间,v2 方案会将 APK 文件视为 Blob,并对整个文件进行签名检查。对 APK 进行的任何修改(包括对 ZIP 元数据进行的修改)都会使 APK 签名作废。这种形式的 APK 验证不仅速度要快得多,而且能够发现更多种未经授权的修改。
新的签名格式向后兼容,因此,使用这种新格式签名的 APK 可在更低版本的 Android 设备上进行安装(会直接忽略添加到 APK 的额外数据),但前提是这些 APK 还带有 v1 签名。
![](https://img.haomeiwen.com/i4055449/ff019b8df60fda02.png)
验证程序会对照存储在“APK 签名分块”中的 v2 签名对 APK 的全文件哈希进行验证。该哈希涵盖除“APK 签名分块”(其中包含 v2 签名)之外的所有内容。在“APK 签名分块”以外对 APK 进行的任何修改都会使 APK 的 v2 签名作废。v2 签名被删除的 APK 也会被拒绝,因为 v1 签名指明相应 APK 带有 v2 签名,所以 Android Nougat 及更高版本会拒绝使用 v1 签名验证 APK。
如需关于 APK 签名验证过程的详细信息,请参阅 APK 签名方案 v2 的“验证”部分。
4.3 APK 签名方案 v2 验证
- 找到“APK 签名分块”并验证以下内容:
“APK 签名分块”的两个大小字段包含相同的值。
“ZIP 中央目录结尾”紧跟在“ZIP 中央目录”记录后面。
“ZIP 中央目录结尾”之后没有任何数据。 - 找到“APK 签名分块”中的第一个“APK 签名方案 v2 分块”。如果 v2 分块存在,则继续执行第 3 步。否则,回退至使用 v1 方案验证 APK。
- 对“APK 签名方案 v2 分块”中的每个 signer 执行以下操作:
a. 从 signatures 中选择安全系数最高的受支持 signature algorithm ID。安全系数排序取决于各个实现/平台版本。
b.使用 public key 并对照 signed data 验证 signatures 中对应的 signature。(现在可以安全地解析 signed data 了。)
c.验证 digests 和 signatures 中的签名算法 ID 列表(有序列表)是否相同。(这是为了防止删除/添加签名。)
d.使用签名算法所用的同一种摘要算法计算 APK 内容的摘要。
e.验证计算出的摘要是否与 digests 中对应的 digest 相同。
f.验证 certificates 中第一个 certificate 的 SubjectPublicKeyInfo 是否与 public key 相同。 - 如果找到了至少一个 signer,并且对于每个找到的 signer,第 3 步都取得了成功,APK 验证将会成功。
注意:如果第 3 步或第 4 步失败了,则不得使用 v1 方案验证 APK。
4.4 JAR 已签名的 APK 的验证(v1 方案)
JAR 已签名的 APK 是一种标准的已签名 JAR,其中包含的条目必须与 META-INF/MANIFEST.MF 中列出的条目完全相同,并且所有条目都必须已由同一组签名者签名。其完整性按照以下方式进行验证:
- 每个签名者均由一个包含 META-INF/<signer>.SF 和 META-INF/<signer>.(RSA|DSA|EC) 的 JAR 条目来表示。
- <signer>.(RSA|DSA|EC) 是具有 SignedData 结构的 PKCS #7 CMS ContentInfo,其签名通过 <signer>.SF 文件进行验证。
3.<signer>.SF 文件包含 META-INF/MANIFEST.MF 的全文件摘要和 META-INF/MANIFEST.MF 各个部分的摘要。需要验证 MANIFEST.MF 的全文件摘要。如果该验证失败,则改为验证 MANIFEST.MF 各个部分的摘要。 - 对于每个受完整性保护的 JAR 条目,META-INF/MANIFEST.MF 都包含一个具有相应名称的部分,其中包含相应条目未压缩内容的摘要。所有这些摘要都需要验证。
5.如果 APK 包含未在 MANIFEST.MF 中列出且不属于 JAR 签名一部分的 JAR 条目,APK 验证将会失败。
因此,保护链是每个受完整性保护的 JAR 条目的 <signer>.(RSA|DSA|EC) -> <signer>.SF -> MANIFEST.MF -> 内容。
四、 参考资料
https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File
https://source.android.com/security/apksigning/?hl=zh-cn
https://baike.baidu.com/item/%E6%95%B0%E5%AD%97%E7%AD%BE%E5%90%8D
http://www.jianshu.com/p/6f8fc521512e(apk安装过程,其中包含了签名验证)
http://blog.csdn.net/jiangwei0910410003/article/details/50402000
https://source.android.com/security/overview/app-security?hl=zh-cn
http://blog.csdn.net/u013836857/article/details/51445532
网友评论