Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >安卓安装包签名_笔记签名验证

安卓安装包签名_笔记签名验证

作者头像
全栈程序员站长
发布于 2022-11-17 09:45:40
发布于 2022-11-17 09:45:40
1.4K00
代码可运行
举报
运行总次数:0
代码可运行

我们知道,一款Android 要发布的话,必须经过签名,Android目前支持的签名方式包括三种:

为了最大限度地提高兼容性,请按照 v1、v2、v3 的先后顺序采用所有方案对应用进行签名。与只通过 v1 方案签名的应用相比,还通过 v2+ 方案签名的应用能够更快速地安装到 Android 7.0 及更高版本的设备上。更低版本的 Android 平台会忽略 v2+ 签名,这就需要应用包含 v1 签名。

v1签名方案

在v1方案中,签名只保护apk中的元数据,也就是单个文件。apk其实就是一个zip文件,我们将打包签名好的apk文件,用解压缩文件解压,就可以看到一个名称为META-INF的文件夹里面。

在META-INF文件夹中,存在3个文件,MANIFEST.MF , CERT.SF,CERT.RSA。这些就是v1版本的apk在安装时候,进行签名校验 很重要的文件。

MANIFEST.MF

这个文件中保存着apk解压之后,所有文件(非文件夹)的信息,看下面的一段内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Manifest-Version: 1.0
Built-By: Generated-by-ADT
Created-By: Android Gradle 3.2.0

Name: AndroidManifest.xml
SHA1-Digest: g+psNXzyZSKU8DMfQr8FdR0KjXI=

Name: LICENSES
SHA1-Digest: +7g2kf8cIIZknpabOMYpXi8vrK8=

Name: META-INF/android.arch.core_runtime.version
SHA1-Digest: OxxKFJcpzAROGjnfMbNijNv1+JU=

Name: META-INF/android.arch.lifecycle_extensions.version
SHA1-Digest: BeF7ZGqBckDCBhhvlPj0xwl01dw=

Jetbrains全家桶1年46,售后保障稳定

在每个文件块中,其中 name就是解压之后,文件的名称(包含路径),而SHA1-Digets就是对文件的内容提取摘要之后 进行Base64之后生成的字符串内容。

CERT.SF

先看一段CERT.SF的内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Signature-Version: 1.0
Created-By: 1.0 (Android)
SHA1-Digest-Manifest: 00yHda1FOBSkUAwjlTfipwkY+0k=
X-Android-APK-Signed: 2

Name: AndroidManifest.xml
SHA1-Digest: BNl/B2KAFMNJ1keEnqQ5+vkw8mY=

Name: LICENSES
SHA1-Digest: 9irOepAoIoOn8huusmI9KxjOT6c=

Name: META-INF/android.arch.core_runtime.version
SHA1-Digest: gfKdTxzy15iV0z7ZogHp7+qdek8=

SHA1-Digest-Manifest :是对整个MANIFEST.MF使用 SHA1算法之后,生成的Base64的编码的字符串。

Name:也是对应解压之后的文件的名称

SHA1-Digest:是对MANIFEST.MF中对应名称(Name)做SHA1之后生成再生成的Base64编码的字符串

CERT.RSA

这里会把之前生成的CERT.SF文件,用我们私钥计算出签名,然后将签名以及包含公钥信息的数字证书一同写入CERT.RSA中保存。

在mac电脑中,我们可以在终端中使用以下命令查看CERT.SF的内容:

openssl pkcs7 -inform DER -in CERT.RSA -text -noout -print_certs

其中CERT.RSA 表示的是文件CERT.RSA ,如果不是在当前文件夹中,应该填写CERT.RSA 的相对路径或者绝对路径。

可以用一张图来解释签名的过程:

安装校验过程。

我们从激活成功教程 sign.apk的过程来讲解校验的过程。首先由于v1是针对单一文件进行提取摘要的方式进行校验。

1.假如,我们破坏或者修改了apk中的某一个文件,那么我们必须修改MANIFEST.MF中的对应文件的摘要值,才能通过sdk对MANIFEST.MF的校验。

2.就算我们修改某个文件之后,并且修改了对应的MANIFEST.MF里面的摘要之后,由于CERT.SF中保存的是未修改之前的MANIFEST.MF中每个条目的SHA1之后的Base64编码值,因此前后比对,不一样。第二步对CERT.SF的校验,也不会通过。只有我们在修改MANIFEST.MF 摘要的同时,也修改CERT.SF对应条目的摘要值,才能通过第二步对CERT.SF的检测。

3前面两步通过伪装修改的方式对MANIFEST.MF和CERT.SF的校验都通过了的话,那么第三步CERT.RSA 的校验,就不可能伪装了,因为CERT.RSA 使用的是开发者的私钥信息进行的签名。用户无法获得其私钥信息,没法伪装。

v1版本签名下的多渠道包实现

既然上面的签名校验方式,不允许我们对apk解压之后的某个文件的修改。 我们就可以不破坏这种校验机制增加文件,来记录apk包的渠道信息。或者利用zip的文件格式来做文章存储我们的渠道信息。市面上有2种对v1签名生成多渠道包的方式。

方式1:们可以在不改变原来apk中任何单个文件的情况下,通过对apk增加文件的方式来记录相关的渠道信息。实现多渠道打包。

我们可以在META-INF,或者apk包解压的任何文件夹位置添加一个我们自己的文件,文件名称如上面channel_xiaomi.txt,以文件名称作为渠道名,然后再重新生成apk的 zip文件。因为上面的MANIFEST.MF ,CERT.SF ,CERT.RSA是对apk解压之后的每个单独文件进行校验,但是我们增减的channel_xiaomi.txt是在生成渠道包之后,重新加入进去的,所以android系统安装apk的时候,我们增加的channel_xiaomi.txt并不在我们android系统校验的范围内,我们就可以在app内,读取这个文件的名称来获取对应的渠道。这里主要耗费的时间是对apk解压之后生成channel_xxx.txt的空文件,然后重新打包成.apk文件。

方式二:利用zip文件的文件格式,我们可以在文件最后的部分的comment(注释)中加入自己的渠道信息,然后再app中去读去zip文件的comment里面的内容,读去到对应的渠道号。这里主要是对zip文件的操作。

V2签名方案

Android 7.0(Nougat)引入一项新的应用签名方案APK Signature Scheme v2,它是一个对全文件进行签名的方案,能提供更快的应用安装、对未授权APK文件的更改提供更多保护,在默认情况下,Android Gradle 2.2.0插件会使用APK Signature Scheme v2和传统签名方案来签署你的应用。

目前该方案不是强制性的,在 build.gradle 添加 v2SigningEnabled false ,就能使用传统签名方案来签署我们的应用(见下面的代码片段)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
android {
    ...
    defaultConfig { ... }
    signingConfigs {
      release {
        storeFile file("xxx.keystore")
        storePassword "password"
        keyAlias "MyReleaseKey"
        keyPassword "password"
        v2SigningEnabled false
      }
    }
  }

APK 签名方案 v2 是一种全文件签名方案,该方案能够发现对 APK 的受保护部分进行的所有更改,从而有助于加快验证速度并增强完整性保护。使用 APK 签名方案 v2 进行签名时,会在 APK 文件中插入一个 APK签名分块,该分块位于“ZIP 中央目录”部分之前并紧邻该部分。在“APK 签名分块”内,v2 签名和签名者身份信息会存储在 APK 签名方案 v2 分块中。

新的签名方案会在ZIP文件格式的 Central Directory 区块所在文件位置的前面添加一个APK Signing Block区块。整个APK(ZIP文件格式)会被分为以下四个区块: 1. Contents of ZIP entries(from offset 0 until the start of APK Signing Block) 2. APK Signing Block 3. ZIP Central Directory 4. ZIP End of Central Directory。

之前的渠道包生成方案是通过在META-INF目录下添加空文件,用空文件的名称来作为渠道的唯一标识,之前在META-INF下添加文件是不需要重新签名应用的,这样会节省不少打包的时间,从而提高打渠道包的速度。但在新的应用签名方案下META-INF已经被列入了保护区了,向META-INF添加空文件的方案会对区块1、3、4都会有影响,v2签名方案签署的应用经过我们旧的生成渠道包方案处理后,在安装时会报以下错误:

Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: Failed to collect certificates from base.apk: META-INF/CERT.SF indicates base.apk is signed using APK Signature Scheme v2, but no such signature was found. Signature stripped?]

目前V1签名另外一种比较流行的往APK中添加ZIP Comment,生成多渠道包的方案,也因为上述原因,无法在新的应用签名方案下进行正常工作。

既然v1签名生成多渠道包的方式对于v2不能使用,那么就需要找另外的出路了。

既然v2签名保护1,3,4块数据区,不能对1,3,4区快的数据做修改,那么就可以在2 数据区 Apk Signing block做修改,在这块数据加入我们的渠道信息。

APK 签名分块

为了保持与 v1 APK 格式向后兼容,v2 及更高版本的 APK 签名会存储在“APK 签名分块”内,该分块是为了支持 APK 签名方案 v2 而引入的一个新容器。在 APK 文件中,“APK 签名分块”位于“ZIP 中央目录”(位于文件末尾)之前并紧邻该部分。

该分块包含多个“ID-值”对,所采用的封装方式有助于更轻松地在 APK 中找到该分块。APK 的 v2 签名会存储为一个“ID-值”对,其中 ID 为 0x7109871a

数据

字节数

描述

size of blcok

8个字节

除此字段外 block的总长度

id-value-pairs

8个字节

此id与value 数据的总长度

id

4个字节

id数据

value

n个字节

value数据

size of block

8个字节

与第一个字段相同

magic

16个字节

魔数,标记block的数据格式

在解析 APK 时,首先要通过以下方法找到“ZIP 中央目录”的起始位置:在文件末尾找到“ZIP 中央目录结尾”记录,然后从该记录中读取“中央目录”的起始偏移量。通过 magic 值,可以快速确定“中央目录”前方可能是“APK 签名分块”。然后,通过 size of block 值,可以高效地找到该分块在文件中的起始位置。在解译该分块时,应忽略 ID 未知的“ID-值”对.

验证

在 Android 7.0 及更高版本中,可以根据 APK 签名方案 v2+ 或 JAR 签名(v1 方案)验证 APK。更低版本的平台会忽略 v2 签名,仅验证 v1 签名。

通过上图可以看出新的应用签名方案的验证过程:

1. 寻找APK Signing Block,如果能够找到,则进行验证,验证成功则继续进行安装,如果失败了则终止安装

2. 如果未找到APK Signing Block,则执行原来的签名验证机制,也是验证成功则继续进行安装,如果失败了则终止安装。

在参考文章中,zip的文件格式中我们可以知道End of Central Directory的这块的数据格式,如下:

Offset

Bytes

Description

0

4

End of central directory signature = 0x06054b50

核心目录结束标记,固定为0x06054b50

4

2

Number of this disk

当前的磁盘编号

6

2

Disk where central directory starts

核心目录开始的磁盘编号

8

2

Number of central directory records on this disk

磁盘上所记录的核心目录数量

10

2

Total number of central directory records

核心目录的总数

12

4

Size of central directory (bytes)

核心目录的大小

16

4

Offset of start of central directory, relative to start of archive

核心目录开始位置相对于archive的偏移

20

2

Comment length (n)

注释的长度

22

n

Comment

注释的内容

知道apk的文件结构,这样可以从apk(实质就是zip文件) EOCD,反推出Central Directory的位置,最后确定是否有APK signing Block,然后确认是否是v2签名,同时我们也可以在APK signing Block这块内容增加一个固定的id(不与ID 0x7109871a重复就行)-value对,来存放我们apk的channel信息,这样就不会破坏整个apk的签名信息,又可以增加我们的渠道信息。

在使用美团打包walle的时候,如果你的build-tools 版本较高的话,可能打出来的包,无法在Android P 上安装。因为 android p 需要 apksigningblock 的长度确保为 4096 的倍数。具体的解决方案在这里

V3签名方案

Android 9 支持 APK秘钥轮替,这使应用能够在 APK 更新过程中更改其签名密钥。为了实现轮替,APK 必须指示新旧签名密钥之间的信任级别。为了支持密钥轮替,google将 APK签名从 v2 更新为 v3,以允许使用新旧密钥。v3 在 APK 签名分块中添加了有关受支持的 SDK 版本和 proof-of-rotation 结构的信息。

参考文章:

APK 签名方案 v2 | Android 开源项目 | Android Open Source Project

zip文件格式

美团自动化打包实践

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/219073.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月28日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
APK 签名:v1 v2 v3 v4
通过对 Apk 进行签名,开发者可以证明对 Apk 的所有权和控制权,可用于安装和更新其应用。而在 Android 设备上的安装 Apk ,如果是一个没有被签名的 Apk,则会被拒绝安装。
全栈程序员站长
2022/08/30
2.3K0
APK 签名:v1 v2 v3 v4
AndroidV1,V2,V3签名原理详解
背景介绍: 一般开发者会指定使用自己创建的证书,如果没有指定,则会默认使用系统的证书,该默认的证书存储在C:\Users\admin.android\debug.keystore,不同的电脑可能安装不同路径。一个签名证书文件中,是包含一对公私钥,用私钥对apk进行签名,在安装到android手机时,系统会使用证书中对应签名私钥的公钥来验证,查看apk是否被更改过,如果没有则可以安装在手机上。任何的app store都不允许使用默认的debug.keystore打包的apk发布上去,因为debug.keystore的密码是默认的,不安全。 一,没有签名的APK无法安装 Android的APK要进行签名才能够安装到手机上,这是因为在安装的时候系统会进行检测,平时我们直接点AS里面那个绿色的运行按钮也能够直接安装到手机上,这是因为其实它也进行了签名,只不过AS自动帮我们做了这个操作有个默认的签名
北洋
2021/12/08
1.1K0
AndroidV1,V2,V3签名原理详解
Android V1及V2签名签名原理简析
Android为了保证系统及应用的安全性,在安装APK的时候需要校验包的完整性,同时,对于覆盖安装的场景还要校验新旧是否匹配,这两者都是通过Android签名机制来进行保证的,本文就简单看下Android的签名与校验原理,分一下几个部分分析下:
看书的小蜗牛
2019/05/14
2.8K0
分析 Android V2 新签名打包机制
QQ音乐技术团队
2017/10/31
6.7K0
分析 Android V2 新签名打包机制
细说Android apk四代签名:APK v1、APK v2、APK v3、APK v4
大部分开发者对apk签名还停留在APK v2,对APK v3和APK v4了解很少,而且网上大部分文章讲解的含糊不清,所以根据官网文档重新整理一份。
BennuCTech
2021/12/10
6.8K0
细说Android apk四代签名:APK v1、APK v2、APK v3、APK v4
【Android 安全】DEX 加密 ( 代理 Application 开发 | 解压 apk 文件 | 判定是否是第一次启动 | 递归删除文件操作 | 解压 Zip 文件操作 )
在 【Android 安全】DEX 加密 ( 支持多 DEX 的 Android 工程结构 ) 博客中介绍了 DEX 加密工程的基本结构 ,
韩曙亮
2023/03/28
1.3K0
Android APK 签名校验[通俗易懂]
非对称加密算法需要两个密钥:公开密钥(简称公钥)和私有密钥(简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
全栈程序员站长
2022/09/03
5.5K0
Android APK 签名校验[通俗易懂]
新一代开源Android渠道包生成工具Walle
在Android 7.0(Nougat)推出了新的应用签名方案APK Signature Scheme v2后,之前快速生成渠道包的方式(美团Android自动化之旅—生成渠道包)已经行不通了,在此应用签名方案下如何快速生成渠道包呢? 本文会对新的应用签名方案APK Signature Scheme v2以及新一代渠道生成工具进行详细深入的介绍。 新的应用签名方案APK Signature Scheme v2 Android 7.0(Nougat)引入一项新的应用签名方案APK Signature Sch
美团技术团队
2018/03/12
1.2K0
新一代开源Android渠道包生成工具Walle
Android应用签名、反编译与防止二次签名
我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行。签名就代表着自己的身份即keystore。小编所在项目,遇到应用被恶意篡改的情况。新版本客户端加入了在线签名逻辑以及防止二次签名逻辑。小编对相关知识加深了理解,并运用在项目测试中,分享给大家。
用户5521279
2019/06/02
5.5K0
Android 新一代多渠道打包神器
李涛
2017/04/21
6.5K2
Android 新一代多渠道打包神器
APK签名原理
网上已有多篇分析签名的类似文章,但是都有一个共同的问题,就是概念混乱,混乱的一塌糊涂。
全栈程序员站长
2022/07/01
8670
实现Android APK瘦身99.99%
让我们将这一原则应用到 Android App 开发中。我们将玩转一个称为“ApkGolf”的 APK,目的是创建一个尽可能具有最少字节数的 App,并可安装在运行 Oreo 的设备上。
Android技术干货分享
2019/06/13
2K0
探究 Android 签名机制和原理
最近在调研一个测试工具的使用,在使用中发现被测试工具处理过的apk文件经安装后打开就会崩溃,分析崩溃日志后原因是签名不一致导致的。
用户5521279
2020/08/30
3.2K0
速读原著-Android应用开发入门教程(HelloActivity的编译结构)
在 Android 的 SDK 环境开发中,HelloActivity 工程经过编译后,SDK 环境下开发生成的所有目标文件均在当前工程目录中,包含了 assets、bin、gen 等目录。
cwl_java
2020/01/15
2560
你可能还不知道的apk签名绕过方法
近期更新Android应用可要注意了,不要随意点个链接就升级,你的正宗应用可能升级成山寨应用哦。 Google在12月发布的安全公告中提到的“Janus”漏洞,可使攻击者在不改变原应用签名的情况上,注入恶意代码。
Erwin
2020/01/02
3.4K0
移动安全(二)|APK打包流程及签名安全机制初探
切入正题,胡小毛在学习Android逆向的过程中又有所总结,先来看看apk文件结构:
用户1631416
2020/03/12
1.1K0
android如何多渠道打包?
关于如何多渠道打包,以下文字详细解答了Android如何实现多渠道打包以及快速打包。
分你一些日落
2021/11/25
1.5K0
浅谈程序的数字签名
数字签名它是基于非对称密钥加密技术与数字摘要算法技术的应用,它是一个包含电子文件信息以及发送者身份,并能够鉴别发送者身份以及发送信息是否被篡改的一段数字串。
小道安全
2022/12/03
1.9K0
浅谈程序的数字签名
android签名原理
什么是签名? 在Apk中写入一个“指纹”。指纹写入以后,Apk中有任何修改,都会导致这个指纹无效,Android系统在安装Apk进行签名校验时就会不通过,从而保证了安全性。
老马的编程之旅
2022/06/22
1.2K0
Android签名攻与防
JNI全称是Java Native Interface(Java本地接口)单词首字母的缩写,本地接口就是指用C和C++开发的接口。由于JNI是JVM规范中的一部份,因此可以将我们写的JNI程序在任何实现了JNI规范的Java虚拟机中运行。同时,这个特性使我们可以复用以前用C/C++写的大量代码。JNI目前提供两种注册方式,静态注册方式实现较为简单,但有一些系列的缺陷,动态注册要复写JNI_OnLoad函数,过程稍微复杂。
Anymarvel
2018/10/22
2.3K0
Android签名攻与防
推荐阅读
相关推荐
APK 签名:v1 v2 v3 v4
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验