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安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

C#中的Converter的具体应用

《C#中的Converter的具体应用》C#中的Converter提供了一种灵活的类型转换机制,本文详细介绍了Converter的基本概念、使用场景,具有一定的参考价值,感兴趣的可以了解一下... 目录Converter的基本概念1. Converter委托2. 使用场景布尔型转换示例示例1:简单的字符串到

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

2025版mysql8.0.41 winx64 手动安装详细教程

《2025版mysql8.0.41winx64手动安装详细教程》本文指导Windows系统下MySQL安装配置,包含解压、设置环境变量、my.ini配置、初始化密码获取、服务安装与手动启动等步骤,... 目录一、下载安装包二、配置环境变量三、安装配置四、启动 mysql 服务,修改密码一、下载安装包安装地