软件测试 | 应用程序签名机制实现的源代码分析
Android 采用签名机制来保护应用程序的安全,以便于开发者进行身份鉴别,防止替换应用程序包和篡改内容。同时有助于在应用程序之间建立一种信任,可以由同一个私钥签名的若干个应用程序共享代码和数据。
Android 系统签名主要有 ROM 签名和应用程序 APk 签名两种形式。ROM 签名是针对已经生成的 Android 系统 ROM 包进行签名。应用程序 APK 签名是针对开发者开发的应用程序安装包 APK 进行签名。前者是对整个 Android 系统包签名,后者只对 Android 系统中一个应用程序 APK 签名。这里仅对 APK 签名的执行过程进行代码层面的分析,流程如图所示。
Android 应用程序 APK 是 jar 包,签名采用的工具是 signapk.jar 包,对应用程序安装包签名的执行命令如下:
此命令实现了对应用程序安装包 input.apk 签名的功能。在 signapk.jar 命令中,第一个参数为公钥 publickey,第二个参数为私钥 privatekey,第三个参数为输入的报名,第四个参数签名后生成的输入包名。在此命令中,signapk.jar 使用公钥 publickey 和私钥 privatekey 对 input.apk 安装包进行签名,生成 output.apk 包。signapk 源码位于 build/tools/signapk/SignApk.java 中。
完成签名后 APK 包中多了一个 META-INF 文件夹,其中有名为 MANIFEST.MF、CERT.SF 和 CERT.RSA 的三个文件。MANIFEST.MF 文件中包含很多 APK 包信息,如 manifest 文件版本、签名版本、应用程序相关属性、签名相关属性等。CERT.SF 是明文的签名证书,通过采用私钥进行签名得到。CERT.RST 是密文的签名证书,通过公钥生成的。MANIFEST.MF、CERT.SF 和 CERT.RSA 三个文件所使用的公钥和私钥的生成可以通过 development/tools/make_key 来获得。下面分被介绍 MANIFEST.MF、CERT.SR 和 CERT.RSA 三个文件生成方法。
(1)生成 MANIFEST.MF 文件
生成 MANIFEST.MF 是对 APK 包中所有未签名文件逐个用算法 SHA1 进行数字签名,再对数字签名信息采用 Base64 进行编码,最后将编完码的签名写 MANIFEST.MFWEN 文件中。添加数字签名到 manifest 文件通过调用 addDigestsToManifest 方法实现,具体代码如下:
需要说明,生成 MANIFEST.MF 使用 SHA1 算法进行数字签名,SHA1 是一种 Hash 算法,两个不同的信息经 Hash 运算后不回产生同样的信息摘要,由于 SHA1 是单向的,所以不可能从消息摘要中复原原文。如果恶意程序改变了 APK 包中的文件,那么在进行 APK 安装校验时,改变后的摘要信息与 MANIFEST.MF 的检验信息不同,应用程序便不能安装成功。
(2)生成 CETR.SF 文件
在生成 MANIFEST.MF 文件之后,用 SHA1-RSA 算法对其进行私钥签名,便生成 CERT.SF。具体代码如下:
RSA 是目前最有影响力的公钥加密算法,是一种非对称加密算法、能够同时用于加密和数字签字。由于 RAS 是对非对称加密算法,因此用私钥对生成 MANIFEST.MF 的数字签名加密后,在 APK 安装时只能使用公钥才能解密它。
(3)生成 CERT.RSA 文件
生成 CERT.RSA 文件与生成 CERT.SF 文件不同之处在于,生成 CERT.RSA 文件使用了公钥文件。CERT.RSA 文件中保存了公钥以及所用的采用加密算法等信息。具体代码如下:
通过以上对 Android 应用程序签名的代码分析,可以看出 Android 系统通过对第三方 APK 包进行签名,达到保护系统安全的目的。应用程序签名只要用于对开发者身份进行识别,达到防范恶意攻击的目的,但不能有效地限制应用程序被恶意修改,只能够检测应用程序是否被修改过,如果应用程序被修改应该再采取相应的应对措施。
搜索微信公众号:霍格沃兹测试学院
评论