Android10.0应用安装白名单---添加签名校验

2024-05-15 06:58

本文主要是介绍Android10.0应用安装白名单---添加签名校验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

为了避免系统被安装上各种各样的app,客户要求系统需要有个安装白名单的功能。

文章目录

  • 背景
  • 思路
  • Android应用签名
  • apk安装白名单进行签名校验
    • 获取apk签名的证书指纹
    • android源码中获取证书指纹
    • 签名校验
  • 结语
  • 微信公众号

思路

白名单功能主要是通过确认要安装的应用是否在白名单上,如果不在,则不允许安装。筛选的标准可以通过包名进行判断。但单纯包名进行判断还是不够安全,这里是想再加个签名校验的机制,毕竟每个签名都是独一无二的。

这个过程,主要难点在于如何获取各个apk签名。在说明如何在代码中获取到系统签名之前,先大概说下Android应用的签名机制。

Android应用签名

签名的基本目的就是不允许apk内部任意一个文件的内容被篡改。所以得保证每个文件都被加密到。
将任意一个签过名的apk进行解压,都可以发现一个叫META-INF的文件夹,该文件夹包括但不限于如下三个文件:

CERT.RSA CERT.SF MANIFEST.MF

1.MANIFEST.MF文件。对APK包中每个文件(文件夹和签名文件除外)进行遍历,使用SHA1或者SHA256生成摘要信息。然后再用base64进行编码,截取MANIFEST.MF文件中某一段:

Name: AndroidManifest.xml
SHA1-Digest: D2yOY7wstlBC3AbjQznUDa6/8Xw=

这里我们可以自己对AndroidManifest.xml这个文件通过SHA1生成摘要信息,有在线的SHA1:

http://www.metools.info/code/c92.html

在这里插入图片描述

拿到摘要后,可以通过在线base64编码,将此摘要进行编码:

http://tomeko.net/online_tools/hex_to_base64.php?lang=en

在这里插入图片描述

可以看到这里获取到的base64编码结果跟MANIFEST.MF文件描述的一样。

其余文件的base64编码也是如此计算得来。从这里就知道,如果apk中的文件被篡改了,则最终得到的base64编码跟MANIFEST.MF文件描述不一样,就会导致安装出错。当然,也可以手动计算出所修改文件的base64编码,然后更新到MANIFEST.MF文件中,但也会功亏一篑,因为还有CERT.RSA和CERT.SF。

2.CERT.SF文件。截取部分该文件:

Signature-Version: 1.0
SHA1-Digest-Manifest: iaeBE2KJWElTbmMNGnjxretMvz8=
Created-By: 1.0 (Android SignApk)Name: kotlin/collections/MapWithDefault.kotlin_metadata
SHA1-Digest: je8WuIzQjM5yX2bkDmjjyviMxOE=Name: kotlin/coroutines/intrinsics/CoroutinesIntrinsicsHKt.kotlin_metadata
SHA1-Digest: reRpbwjfyR7tladgIdLzjpREduA=Name: res/interpolator/btn_checkbox_checked_mtrl_animation_interpolator_0.xml
SHA1-Digest: 9Lo7vzAcNsmM/qCg9/iamygexzk=

这个文件是对MANIFEST.MF文件中的每一项再做一次SHA1计算,然后再进行base64编码。另外还对MANIFEST.MF文件的内容进行SHA1计算,然后进行编码,将该值写到SHA1-Digest-Manifest中:

SHA1-Digest-Manifest: iaeBE2KJWElTbmMNGnjxretMvz8=

这里对MANIFEST.MF文件进行了一层篡改保护,只要MANIFEST.MF文件被修改过,那最后得到的base64编码肯定对不上。当然,到此为止,如果只是做到这一步,那还是可以被篡改的。关键看看CERT.RSA文件。

3.CERT.RSA文件。该文件保存了公钥,所采用的加密算法等信息。还有比较重要的是,对CERT.SF文件的内容用私钥进行加密之后的值。也就是说,即使手动篡改了MANIFEST.MF文件和CERT.SF文件,CERT.RSA文件还是会对应不上,安装就会失败。

apk安装白名单进行签名校验

上面所说是签名的过程,而安装则是反过来。

CERT.RSA这个文件中的包含的公钥对数字签名(自己本身)进行解密,将解密后的结果与CERT.SF文件hash运算后的结果进行比对,一致的话就返回证书链信息,并将证书链保存在certificates对象中,同时说明CERT.SF文件没有被篡改。如果这里对比通过,则下一步就验证MANIFEST.MF是否被篡改。在这一步,会遍历每个文件(entry),对非文件夹非签名文件的文件,逐个生成SHA1的数字签名信息,再用Base64进行编码,并与MANIFEST.MF中对内容进行比对,若一一对应,则表示文件没被篡改。到这里校验APK所有文件是否有被篡改,也已完成。

显然,如果我们想要在安装白名单上实现签名校验,那可以对比RSA文件上的证书签名是否与apk的签名一致即可。

获取apk签名的证书指纹

拿到app后,通过解压apk,获取到CERT.RSA文件,执行如下指令:

keytool -printcert -file CERT.RSA

会可以得到签名的证书指纹:

Certificate fingerprints:MD5:  0E:BA:50:A4:5C:15:B3:5D:97:7D:04:D8:43:79:B3:58SHA1: 41:79:1C:9B:8F:AF:15:E1:AC:D5:AA:F5:92:10:FD:42:46:7D:82:70SHA256: 2D:37:0C:21:F5:DF:D5:53:D2:A7:96:31:4B:70:92:5F:B3:8A:DE:EF:90:86:4C:92:0B:BB:BB:12:88:7D:35:20

每个签名的证书指纹都是唯一的,如此一来,就可以通过该证书指纹的唯一性来进行签名校验了。

android源码中获取证书指纹

要想获取apk的签名证书指纹,就需要先获取其签名。app安装时通过PackageParser类来解析安装包的信息,而签名也包含其中。我们可以利用这个来获取到签名的证书指纹。具体的安装流程这里不多介绍,直接定位到PackageManagerService类的preparePackageLI方法,该方法会去new出一个PackageParser对象来做apk包的解析:

private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)throws PrepareFailure {...PackageParser pp = new PackageParser();pp.setSeparateProcesses(mSeparateProcesses);pp.setDisplayMetrics(mMetrics);pp.setCallback(mPackageParserCallback);Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");final PackageParser.Package pkg;try {pkg = pp.parsePackage(tmpPackageFile, parseFlags);DexMetadataHelper.validatePackageDexMetadata(pkg);} catch (PackageParserException e) {throw new PrepareFailure("Failed parse during installPackageLI", e);} finally {Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);}...try {// either use what we've been given or parse directly from the APKif (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {pkg.setSigningDetails(args.signingDetails);} else {PackageParser.collectCertificates(pkg, false /* skipVerify */);}} catch (PackageParserException e) {throw new PrepareFailure("Failed collect during installPackageLI", e);}...
}

这里列出部分代码,pkg是一个Pakage对象,属于PackageParser内部类,该类用于保存apk相关的信息,如包名,apk路径,签名等。

签名拿到后,就可以拿到它的证书指纹了,如下:

String sha1 = getFingerprint(pkg.mSigningDetails.signatures[0], "SHA1");private String getFingerprint(Signature signature, String hashAlgorithm) {if (signature == null) {return null;}try {MessageDigest digest = MessageDigest.getInstance(hashAlgorithm);return toHexadecimalString(digest.digest(signature.toByteArray()));} catch(NoSuchAlgorithmException e) {// ignore}return null;
}

MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。
这里是根据SHA算法获取摘要,即证书指纹。

签名校验

用该指纹和使用keytool得出的SHA1值进行比对,如果符合,则签名校验通过,允许应用安装。具体实现也比较单,可以将keytool得出的SHA1值保存到白名单中,然后在apk安装过程中,再读出进行比对即可。

结语

每个签名的证书指纹,即消息摘要,是哪些内容经过SHA1、MD5、SHA256算法得到的呢?私钥加上其他的一些内容?

微信公众号

我在微信公众号也有写文章,更新比较及时,有兴趣者可以微信搜索【Android系统实战开发】,关注有惊喜哦!

这篇关于Android10.0应用安装白名单---添加签名校验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/991126

相关文章

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

Python安装时常见报错以及解决方案

《Python安装时常见报错以及解决方案》:本文主要介绍在安装Python、配置环境变量、使用pip以及运行Python脚本时常见的错误及其解决方案,文中介绍的非常详细,需要的朋友可以参考下... 目录一、安装 python 时常见报错及解决方案(一)安装包下载失败(二)权限不足二、配置环境变量时常见报错及

MySQL8.2.0安装教程分享

《MySQL8.2.0安装教程分享》这篇文章详细介绍了如何在Windows系统上安装MySQL数据库软件,包括下载、安装、配置和设置环境变量的步骤... 目录mysql的安装图文1.python访问网址2javascript.点击3.进入Downloads向下滑动4.选择Community Server5.

CentOS系统Maven安装教程分享

《CentOS系统Maven安装教程分享》本文介绍了如何在CentOS系统中安装Maven,并提供了一个简单的实际应用案例,安装Maven需要先安装Java和设置环境变量,Maven可以自动管理项目的... 目录准备工作下载并安装Maven常见问题及解决方法实际应用案例总结Maven是一个流行的项目管理工具

MySql9.1.0安装详细教程(最新推荐)

《MySql9.1.0安装详细教程(最新推荐)》MySQL是一个流行的关系型数据库管理系统,支持多线程和多种数据库连接途径,能够处理上千万条记录的大型数据库,本文介绍MySql9.1.0安装详细教程,... 目录mysql介绍:一、下载 Mysql 安装文件二、Mysql 安装教程三、环境配置1.右击此电脑

在 Windows 上安装 DeepSeek 的完整指南(最新推荐)

《在Windows上安装DeepSeek的完整指南(最新推荐)》在Windows上安装DeepSeek的完整指南,包括下载和安装Ollama、下载DeepSeekRXNUMX模型、运行Deep... 目录在www.chinasem.cn Windows 上安装 DeepSeek 的完整指南步骤 1:下载并安装

5分钟获取deepseek api并搭建简易问答应用

《5分钟获取deepseekapi并搭建简易问答应用》本文主要介绍了5分钟获取deepseekapi并搭建简易问答应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1、获取api2、获取base_url和chat_model3、配置模型参数方法一:终端中临时将加

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

Python调用另一个py文件并传递参数常见的方法及其应用场景

《Python调用另一个py文件并传递参数常见的方法及其应用场景》:本文主要介绍在Python中调用另一个py文件并传递参数的几种常见方法,包括使用import语句、exec函数、subproce... 目录前言1. 使用import语句1.1 基本用法1.2 导入特定函数1.3 处理文件路径2. 使用ex

python管理工具之conda安装部署及使用详解

《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3