写点什么

软件测试 | 应用程序签名机制实现的源代码分析

  • 2023-05-31
    北京
  • 本文字数:1778 字

    阅读完需:约 6 分钟

获取更多学习资料

Android 采用签名机制来保护应用程序的安全,以便于开发者进行身份鉴别,防止替换应用程序包和篡改内容。同时有助于在应用程序之间建立一种信任,可以由同一个私钥签名的若干个应用程序共享代码和数据。

Android 系统签名主要有 ROM 签名和应用程序 APk 签名两种形式。ROM 签名是针对已经生成的 Android 系统 ROM 包进行签名。应用程序 APK 签名是针对开发者开发的应用程序安装包 APK 进行签名。前者是对整个 Android 系统包签名,后者只对 Android 系统中一个应用程序 APK 签名。这里仅对 APK 签名的执行过程进行代码层面的分析,流程如图所示。

Android 应用程序 APK 是 jar 包,签名采用的工具是 signapk.jar 包,对应用程序安装包签名的执行命令如下:

Java -jar signapk.jar publickey privatekey input.apk output.apk
复制代码

此命令实现了对应用程序安装包 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 方法实现,具体代码如下:

private static Manifest addDigestsToManifest(JarFile jar){  ......//遍历update.apk包中所有文件//得到签名文件内容InputStream data = jar.getInputStream(entry);
//更新文件内容while ((num = data.read(buffer))>0 ) { md.undate(buffer,0,num);}.....//进行SHA1签名,并采用Base64进行编码attr.putValue("SHA1-Digest",base64.encode(md.digest()));output.getEntries().put(name,attr);....}
复制代码

需要说明,生成 MANIFEST.MF 使用 SHA1 算法进行数字签名,SHA1 是一种 Hash 算法,两个不同的信息经 Hash 运算后不回产生同样的信息摘要,由于 SHA1 是单向的,所以不可能从消息摘要中复原原文。如果恶意程序改变了 APK 包中的文件,那么在进行 APK 安装校验时,改变后的摘要信息与 MANIFEST.MF 的检验信息不同,应用程序便不能安装成功。

(2)生成 CETR.SF 文件

在生成 MANIFEST.MF 文件之后,用 SHA1-RSA 算法对其进行私钥签名,便生成 CERT.SF。具体代码如下:

Signature signature = Signature.getIntance("SHA1withRSA");signature。initSign(privateKey);je = new JarEntry(CERT_SF_NAME);je.setTime(timestamp);outputJar.putNextEntry(je);wrireSignatureFile(manifest,newSignatureOutputStream(outputJar,signature));
复制代码

RSA 是目前最有影响力的公钥加密算法,是一种非对称加密算法、能够同时用于加密和数字签字。由于 RAS 是对非对称加密算法,因此用私钥对生成 MANIFEST.MF 的数字签名加密后,在 APK 安装时只能使用公钥才能解密它。

(3)生成 CERT.RSA 文件

生成 CERT.RSA 文件与生成 CERT.SF 文件不同之处在于,生成 CERT.RSA 文件使用了公钥文件。CERT.RSA 文件中保存了公钥以及所用的采用加密算法等信息。具体代码如下:

js = new JarEntry(CERT_RSA_NAME);je.setTime(timetamp);outputJar.putNextEntry(je);writeSignatureBlock(signature,publickey,outputJar);
复制代码

通过以上对 Android 应用程序签名的代码分析,可以看出 Android 系统通过对第三方 APK 包进行签名,达到保护系统安全的目的。应用程序签名只要用于对开发者身份进行识别,达到防范恶意攻击的目的,但不能有效地限制应用程序被恶意修改,只能够检测应用程序是否被修改过,如果应用程序被修改应该再采取相应的应对措施。

搜索微信公众号:霍格沃兹测试学院

用户头像

社区:ceshiren.com 微信:ceshiren2023 2022-08-29 加入

微信公众号:霍格沃兹测试开发 提供性能测试、自动化测试、测试开发等资料、实事更新一线互联网大厂测试岗位内推需求,共享测试行业动态及资讯,更可零距离接触众多业内大佬

评论

发布
暂无评论
软件测试 | 应用程序签名机制实现的源代码分析_测试_测吧(北京)科技有限公司_InfoQ写作社区