签名的意义
签名主要用于表明开发者的身份和操作权利,在签署APK时,签署工具会将公钥证书附加到 APK。公钥证书充当“指纹”,用于将 APK 关联到开发者。主要用途是在升级应用的时候确保新版应用的来源是开发者本人,并且可以验证应用是否被第三方修改过。
证书
公钥证书(也称数字证书、身份证书)包含公钥以及标示密钥所有者的一些其他数据(如数字签名、签名算法、开发者姓名,居住地等)。
在给APK签名的时候,证书会附加到APK中,用于作为开发者的一项凭证。
密钥库
密钥库则是个包含单个或者多个私钥的二进制文件,在Android 中一般使用JKS文件充当密钥库,这里可以存放许多私钥,当然,密钥库本身会有一个密码,用于保护保存在其中的私钥。
在JDK中,拥有一个Keytool工具,可以用来生成、管理密钥库(XXX.jks)。当然,使用Android Studio的可视化工具也可以方便生成一个密钥库和密钥。
在AS的菜单栏中,点击 Build > Generate Signed APK -> next -> create Key Store,便可看到如下界面:
这样一来便可以创建一个可用于给APK签名的证书和密钥库,密钥对中的公钥是存在证书中,私钥会存在密钥库里,下面通过Keytool随便打开一个密钥库看看密钥的情况。
便可以看到密钥库中存放了一个刚刚创建的studykey密钥。
签名的过程
在签名的过程中会出现消息摘要,MD5/SHA-0 SHA-1,数字签名,base64几个概念:
1.消息摘要(数字指纹)
所谓消息摘要就是对某个消息数据执行单向的hash函数,生成一个固定的hash值,这个hash值就被称为消息摘要。
消息摘要的主要作用是验证数据的完整性,比如在一些论坛上下载XX软件的时候,楼主在给出下载地址的时候往往都会给出一个MD5值,用于检验文件的完整性,MD5便是一种消息摘要的计算算法。
并且计算消息摘要的过程是不可逆的,也就是说无法通过消息摘要推算出消息本身的内容。
2.MD5/SHA-0/SHA-1/SHA-256等
这些都是一种消息摘要的计算算法,并且算法的过程是不可逆的,非常适合作数据完整性的验证工作。
3.数字签名
简单的说,数字签名就是使用开发者的私钥对消息摘要加密后的一个字符串。它的作用是确保数字摘要的来源是真正的开发者,因为只有用开发者的公钥才能够对其进行解密。
4.Base64编码
Base64就是一种基于64个可打印字符来表示二进制数据的方法。 比如想让一张图片在网页上显示,可以考虑将图片所代表的二进制进行Base64编码,然后得到可打印的一串字符串,最后显示在网页上。
签名过程大体上可以分为三步:
a.利用摘要生成算法对APK中的所有文件生成摘要信息。( 这里的摘要显示的是Base64编码过后的加密信息,即,摘要显示内容= Base64(SHA(某个文件)) );
b.利用私钥对我们的摘要信息进行加密,得到数字签名;
c.把摘要信息、数字证书打包到META-INF文件夹中。
根据上面的步骤,对应到具体的文件中可以看到:
摘要信息其实是存储在 MANIFEST.MF
和CERT.SF
文件中的,如下所示:
其实,两个文件是存在关系的,MANIFEST.MF
存储了APK中的所有文件生成一个摘要信息,而CERT.SF
存储的是MANIFEST.MF
的摘要信息,即:MANIFEST.MF
= SHA(项目文件);CERT.SF
= SHA(MANIFEST.MF
)。
说了这么多,下面用一张图片来阐述签名是如何保证APP升级时候的APK是来自原始作者的:
只是初略阅读了相关源码,此图是靠自己理解画出的,如有错误,还请指正
参考资料:
http://blog.csdn.net/jiangwei0910410003/article/details/50402000
https://developer.android.com/studio/publish/app-signing.html?hl=zh-cn#considerations