Android开发签名知识梳理总结

目录
  • 前言
  • 一、签名基础
    • 1. 消息摘要
    • 2. 加密算法
      • 2.1 对称加密
      • 2.2 非对称加密
      • 2.3 使用场景
    • 3. 数字签名
    • 4. 数字证书
  • 二、Android签名机制
    • 1. Android签名机制的异同点
    • 2. Debug和Relase的签名
  • 三、签名方案
    • 1 v1方案
    • 2. v2方案
  • 四、签名过程
    • 1. v3方案
    • 2. v4方案
    • 3. 向下兼容的签名方案

前言

最近帮测试做了一点关于签名的需求,今天就和各位同学简单聊一聊关于签名的那些事儿。

如果问到 Android 为什么需要签名?大家都可能想到官网的解释:

Android 系统要求所有 APK 必须先使用证书进行数字签名,然后才能安装到设备上进行更新。

这是一个比较模糊的解释,简单来说,有了签名,就可以让 App 和开发者绑定。

毕竟,应用那么多,别的开发者也有可能盗用你的代码,这个时候,包名和你相同,代码和你相同,怎么区分你的 App 和这些人的 App 不是同一个呢?

这个时候数字签名就派上用场了。

一、签名基础

想要彻底了解签名知识,我们得了解以下知识:

  • 消息摘要
  • 数字签名
  • 加密
  • 数字证书

这一系列的知识各位可能在学习网络的时候或多或少的接触过。

我们简单的学习一下这些知识:

1. 消息摘要

消息摘要常常被被称为数字摘要或者数字指纹,定义如下:

在原来的数据基础上,经过一个单向的 Hash 计算,得到一个固定的 Hash 值,这就是消息摘要。

常见的摘要算法都有 MD5、SHA-1 和 SHA-256,特点如下:

  • 长度固定,与内容长度无关:比如 MD5 是 128 位、SHA-1 是 160 位、SHA-256 是 256 位。
  • 看似随机,其实不随机:同内容两次摘要得出的结果一致
  • 单向:只能从原数据得出摘要,不能从消息摘要得出原来的数据
  • 优秀的摘要算法很难 Hash 碰撞

基于此,消息摘要常常会被用来检查内容的完整性。

比如我们下载起点读书,消息摘要的用法如下:

  • 计算摘要:App 会针对自己的文件信息计算出一个数字摘要比如 123**...**123
  • 下载App
  • 验证摘要:对下载的 App 再次计算摘要,比如得出的也是 123**...**123,和之前的数字摘要一对比,这就代表我从服务器下载的内容是完整的,可以正常使用

当然,上面值涉及了摘要部分,其他过程,我们后面分析。

2. 加密算法

什么是加密?

百科是这么解释的:

将明文信息改变为难以读取的密文内容,使之不可读的过程。只有拥有解密方法的对象,经由解密过程,才能将密文还原为正常可读的内容。

所以啊,加密方法得到的密文是可以转变为明文的,像信息摘要算法比如 MD5 得出来的结果是不可逆的,所以面试官问你们什么事加密算法的时候,你可不能把 MD5 说进去!

加密算法分为两大类,对称加密非对称加密

2.1 对称加密

对称加密在加密和解密的时候使用的同一把钥匙:

2.2 非对称加密

非对称加密是使用公钥/私钥中的公钥来加密明文,然后使用对应的私钥来解密密文的过程:

简单对比一下对称加密和非对称机密:

  非对称加密 对称加密
速度
效率
安全性
常见算法 RSA\DH AES\DES\IDEA

2.3 使用场景

学过网络的同学应该都了解,在 Https 的传输过程中,客户端和服务端使用非对称加密生成对称加密的密钥,然后用对称加密传输网络中的数据。

比如我上大学那会儿,每个月的月尾我和我妈的对话是这样的:

网络环境是开放的,万一这时,有一个黑客监听了我和我妈的对话,过程就变成了这样:

在我发卡号的时候,黑客将我的卡号改成了它的卡号,于是我的生活费变成了他的生活费。

为了避免这种情况,于是我和我妈约定好了,每次发送前,使用对称加密对消息进行加密,接受消息的时候使用密钥解密,过程就变成了这样:

中间人再也不能获取到消息了,看似一点问题都没有,但是我和老妈之间如何确定密钥呢?

密钥总要在互联网之间进行传输的,有传输就有被中间人截获的风险,一旦被截获,钱可就没了!

为了解决对称加密钥匙传输的问题,我和老妈用上了非对称加密,像这样:

即使这样,还是有问题存在:

  • 怎么才能确认我获得的公钥来自老妈?
  • 如何确定消息确实来自老妈?

解决这两个问题也很简单,一是数字签名,二就是数字证书。

3. 数字签名

数字签名的作用是为了消息的完整性。

在非对称加密的体系下,消息的发送过程是这样的,还是上面的例子:

数字签名的过程是这样的:

  • 我发送消息前,利用 Hash 算法针对数据得出一个摘要
  • 我使用老妈的公钥对摘要内容进行加密,连同对称加密的数据一起发送过去
  • 老妈接收到消息后,先利用对称密钥对内容解密,再进行 Hash 计算得出摘要
  • 老妈使用私钥将摘要内容解密,和再次计算得出的摘要作对比,一致就代表消息无误

上面的这种场景其实有点不妥,数字签名一般用在证书上,协商好对称密钥以后一般不会进行消息完整性校验了,不过大伙只要了解数字签名要来校验消息完整性就好。

截止现在,还有最后一个问题,我无法确认获取的公钥确实来自老妈。

4. 数字证书

证书的作用很简单,证明公钥的身份。

就像在现实中,大家都是怎么证明自己的身份的?

没错,是身份证。你有没有发现,每张身份证,会有三种信息:

  • 自身的信息
  • 置办身份证的派出所
  • 有效期

对应的数字证书也有很多内容:

  • CA:证书的颁发机构
  • 证书的有效期
  • 公钥
  • 证书的授予对象

CA 将这些内容利用 CA 的私钥进行签名,用户使用 CA 的公钥验签,从而证明公钥的身份。

常见的证书分为两种:

  • 签名证书:由 CA 机构颁发,绝大部分网站都采用的这种方式
  • 自签名证书:由服务器自己颁发给自己

重回之前的例子,老妈只需要将自己的签名证书发给我,我就可以获取她的公钥,之后就可以正常的通信。

二、Android签名机制

在 Android 中,也需要使用数字证书做数字签名,数字证书中公钥对应的私钥由开发者持有。

在 Android Studio 中,最终会生成一个 .jks 的文件,早期 Eclipse 是 .keystore,它们都是用作证书和私钥的二进制文件。

App 如果使用了一种私钥签名,另外一个私钥签名的文件将无法安装或覆盖老的版本,这样做是为了防止已经安装的 App 被恶意的第三方覆盖。

1. Android签名机制的异同点

Android 中数字签名的生成和普通的数字签名并没有很大的区别。

但是进行数字签名的证书可以采用自签名证书,即不需要权威证书颁发机构(CA)来做背书,因为它的作用是用来标识应用程序的开发者,下载的用户并不需要这个证书来下载该 App。

2. Debug和Relase的签名

当我们在IDE中运行或调试项目时,AS 会自动使用 Android SDK 工具生成的调试证书为我们的应用签名,路径为 $HOME/.android/debug.keystore,但是应用商店可不接受使用调试证书发布的应用签名。

打包Release时,我们一般会在 app 模块中的 build.gradle 进行配置:

android {
    ...
    signingConfigs {
        release {
            storeFile file("release.keystore")
            storePassword "******"
            keyAlias "******"
            keyPassword "******"
        }
    }
}

这些都是我们生成 .jks 或者 .keystore 需要生成的参数。

三、签名方案

目前 Android 支持以下四种应用签名方案:

  • v1方案:基于 JAR 签名
  • v2方案:Android 7.0 引入,改动大
  • v3方案:Android 9.0 引入,基于 v2 的升级
  • v4方案:Android 11.0 引入,用来支持 ADB 增量 APK 安装

1 v1方案

v1 是一个老生常谈的签名了,签名过程也很简单。

我们如果选中一个任意签名后的 apk 进行解压,会找到一个 META-INF 文件,这个文件里一般会有以 MF、SF 和 RSA 结尾的文件,如图:

这些文件在 v1 签名流程中是这样的:

验证过程在 Apk 安装的过程中:

整个过程清晰明了,但 v1 有两个问题:

第一个问题是签名校验慢,要针对 Apk 中所有的文件进行校验,这会拖累老设备的安装时间。

第二个问题是仅针对 ZIP 条目校验,META-INF 文件不会计入校验过程。这样会导致即使我 Apk 已经签过名,工程师也可以移动条目顺序并重新压缩,也可以修改 META-INF 文件下的内容,带来一些安全隐患,早期的多渠道打包就是在这里做的文章。

2. v2方案

v2 是 Android 签名方案的一大步,它解决了 v1 遗留的签名校验慢和完整性的问题。

我们先来看一下 v2 的组成部分:

v1 的组成部分其实就和 Before signing 那一块儿一样,v2 多了红色区域,我们称之为APK签名分块。

从保护的内容来看,v1 仅保护内容1,v2 保护的区域有 1、3、4 和 2 的 signed data 区域,signed data 是 1、3 和 4 得出来的摘要等信息。

四、签名过程

就一个 App 而言,它可能有一个或者多个签名者,对于每个签名者而言,都会进行签名过程。

v2 没有对每个文件都进行计算,而是针对的所有字节。它将 1、3 和 4 区域都拆分成了大小为 1MB 的连续块,

计算方式如下:

  • 每个小块都按:字节 0xa5 + 块字节长度 + 块内容 进行计算
  • 每个1、3 和 4 块都按:字节 0xa5 + 块数 + 小块摘要 进行计算

最后,将这些一个或者多个签名者的摘要、证书等信息都打包到 Apk 中。

验签过程:

v2 方案的 APK 验证过程是这样的:

  • 找到APK签名分块区域
  • 每找到一个签名者,都会验证:签名算法、信息摘要、证书和公钥
  • 所有的签名者都验证通过了,APK 验证才会通过

1. v3方案

v3 方案建立在 v2 的基础上,目标是解决在更新过程中更改签名密钥的问题。

所以 APK 签名分块中 添加了两部分内容:

  • Proof-of-rotation: 一个存在替换的所有旧签名证书的链表,根节点是最旧的证书
  • SDK 版本支持

v3 和 v2 的签名过程和验证过程几乎一致,就不写出来了。

2. v4方案

如果同学们经常玩一些主机游戏,可以发现,在 PS5 或者 Swtich 上,一些游戏即使没有安装完成,我们也可以打开游戏玩一些基本功能,比如我以前常玩的 NBA 2k 系列。

Android 11 中谷歌也新增了 ADB增量APK安装 功能,比如一个 APK 有 2GB,我下载完 50 MB 以后,就可以使用一些基本功能,剩余的文件通过后台流式传输,不过 Android 11 中的这个功能是面向 ADB 的。

虽然这个功能很赞,但是对签名方案带来了一些挑战,之前的方案都是基于所有文件进行校验的,于是推出 Android 第四代签名方案 v4。

v4 基于 APK 所有的字节计算出 Merkle Hash 树,并将 Merkle 树的根 Hash、盐值作为签名数据进行包完整性校验,v4 签名必须单独存在 .idsig 文件中,不会存在于 APK 文件中,所以 apk 文件中仍然需要 v2 或者 v3 签名。

3. 向下兼容的签名方案

Android 中的签名方案是自上而下兼容的,如图:

对于 Android 11 来说,验证过程是这样的:

  • 是否支持 v4,v4 验证完了再验证 v3 或者 v2
  • v4 不通过,验证 v3
  • v3 不通过,验证 v2
  • v2 不通过,验证 v1
  • v1 不通过,安装失败

对于 Android 9 来说,就得从 v3 方案开始验证的。

到此这篇关于Android开发签名知识梳理总结的文章就介绍到这了,更多相关Android开发签名内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android studio设置指定的签名文件教程

    不废话,直接看怎么弄,下面两张图你就指定啦 配置签名文件和密码(前提你已经有自己的签名文件keystore或者jks) 将上面的签名配置设置到你的Build Types去 这一步已经完成啦,写完代码构建生成的app就是使用的我们设置的keystore了 看一下配置后我们的Build.gradle发生什么变化 看到这里是不是懂了,我就不再多言啦! 补充知识:AndroidStudio统一自己的签名文件(免手动签名) 为了在使用第三方SDK的时候避免自己手动多次打包,需要在build.gradle下

  • Android Studio签名打包的两种方式(图文教程)

    签名打包的两种方式: 注:给我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行.签名就代表着自己的身份(即keystore),多个app可以使用同一个签名. 如果不知道签名是啥意思,请自行百度哦.在eclipse中签名的方法是:选中工程,邮件选择"export-android-export android application", 1.方式1:通过Android Studio进行签名: 选中app这个module,选择菜单栏"Buil

  • Android系统制作自定义签名的例子

    1.简介 应客户要求为了是特殊定制的系统更具安全,系统ROM需要使用自己定义的签名,还有一些特殊的场景也会更改系统的签名比如在过cts认证测试的时候也会修改平台签名才能测试通过关于签名的问题. 这是因为平台默认的是test签名.网上大多说签名的都是app签名而非平台签名. test签名这种类型的key只适用于开发阶段,而且这种秘钥是公开的,谁都可以使用. 当发布一款android产品,就需要另外给整个系统签个名,防止被别人盗用.这种系统就是release版本的Android系统. 这里就简单记录

  • Android 项目正式签名打包教程分享

    大家在开发安卓应用的时候,在调试阶段通常都是通过 run 的方式发布到模拟器或者真机上,我们知道 android 应用打包后的后缀名是 .apk 文件..apk 文件是一种压缩包,类似 .zip 文件,我们可以通过强制更改它的后缀为 .zip 来解压 apk 获取包里的内容,以这种方式可以验证它其实就是一个压缩包. 在 run 的时候就是将我们所写的代码打包为 apk 文件,打包就是根据签名.标识等信息生成的一个安装包,我们在包里嵌入作者的信息.公司信息等,可以具有唯一的辨识行为,同时也可以维护

  • 使用Android Studio实现为系统级的app签名

    我们在做系统级的app开发时,往往会在AndroidManifest.xml文件中添加:android:sharedUserId="android.uid.system"以获取系统级的权限,如果你正在使用Android Studio进行开发,编译生成的apk会因为签名问题无法安装. 此时有两个解决方案, 1,是将编译好的apk放入源码中vender目录下,编写相应的android.mk文件,并在文件中加入: LOCAL_CERTIFICATE := platform 然后使用"

  • Android 自定义View手写签名并保存图片功能

    GIF压缩有问题,运行很顺滑!!! 1.自定义View--支持设置画笔颜色,画笔宽度,画板颜色,清除画板,检查是否有签名,保存画板图片(复制粘贴可直接使用) /** * Created by YyyyQ on 2020/3/5. * 电子签名 */ public class SignatureView extends View { private Context context; //X轴起点 private float x; //Y轴起点 private float y; //画笔 priva

  • Android实现签名涂鸦手写板

    本文实例为大家分享了Android实现签名涂鸦手写板的具体代码,供大家参考,具体内容如下 布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:

  • Android 运用@JvmName解决函数签名冲突问题详解

    Kotlin(JVM) 中定义下面这样两个方函数时,编译器会报错 fun foo(value: List<String>) {} fun foo(value: List<Int>) {} Platform declaration clash: The following declarations have the same JVM signature (method(Ljava/util/List;)V): 因为 Java 的泛型编译期擦除,所以 JVM 无法识别签名中泛型的区别,

  • Android studio导出APP测试包和构建正式签名包

    目录 一.导出APP测试包 二.构建正式签名包 一.导出APP测试包 1.打开你要导出的项目,或者是新建一个项目 2.单击菜单栏的Build -> Build Bundle(s) / APK(s) -> Build APK(s),稍等一段时间,等待系统构建. 3.构建完成后会在屏幕的右下角提示: 4.定位到构建好的app-debug.apk有两种方法: 方法一:直接点击locate方法二: (1)选择project (2)依次点击app -> build ->outputs -&g

  • Android开发签名知识梳理总结

    目录 前言 一.签名基础 1. 消息摘要 2. 加密算法 2.1 对称加密 2.2 非对称加密 2.3 使用场景 3. 数字签名 4. 数字证书 二.Android签名机制 1. Android签名机制的异同点 2. Debug和Relase的签名 三.签名方案 1 v1方案 2. v2方案 四.签名过程 1. v3方案 2. v4方案 3. 向下兼容的签名方案 前言 最近帮测试做了一点关于签名的需求,今天就和各位同学简单聊一聊关于签名的那些事儿. 如果问到 Android 为什么需要签名?大家

  • Android开发必备知识 为什么说Kotlin值得一试

    1.Hello, Kotlin Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly 邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 1.1 Kotlin的身世 写了许久Java,有没有发现其实你写了太多冗余的代码? 后来你体验了一下Python,有没有觉得不写分号的感觉真是超级爽? 你虽然勤勤恳恳,可到头来却被NullPointerException折磨的死去活来,难道就没有受够这种日子么? 直到有一天你发现自己已经写了好几十万行

  • Android微信签名知识的总结

    前言 最近遇到一个项目的应用要上微信登录,大家都知道微信登录是需要开放平台上申请的,在微信开发平台创建移动应用后,需要填写: 需要填写的内容 问题 这里的应用签名是keystore的证书的md5,但是微信的这个只有一个填写输入框,不像百度地图.高德地图那样,有线上的SHA1和开发调试的SHA1两种,那这就纠结了,在开发运行的时候AS IDE默认使用的签名keystore是系统的 debug.keystore,系统的和自己项目线上的keystore的MD5.SHA1肯定是不一样的,那么问题来了,要

  • 如何使用Kotlin进行Android开发

    Kotlin是一门基于JVM的编程语言,它正成长为Android开发中用于替代Java语言的继承者.Java是世界上使用最多的编程语言之一,当其他编程语言为更加便于开发者使用而不断进化时,Java并没有像预期那样及时跟进. Kotlin是由JetBrains创建的基于JVM的编程语言,IntelliJ正是JetBrains的杰作,而Android Studio是基于IntelliJ修改而来的.Kotlin是一门包含很多函数式编程思想的面向对象编程语言. Kotlin生来就是为了弥补Java缺失的

  • Android签名知识小结

    一.为什么要签名 开发Android的人这么多,完全有可能大家都把类名,包名起成了一个同样的名字,这时候如何区分?签名这时候就是起区分作用的. 由于开发商可能通过使用相同的Package Name来混淆替换已经安装的程序,签名可以保证相当名字,但是签名不同的包不被替换. APK如果使用一个key签名,发布时另一个key签名的文件将无法安装或覆盖老的版本,这样可以防止你已安装的应用被恶意的第三方覆盖或替换掉. 这样签名其实也是开发者的身份标识.交易中抵赖等事情发生时,签名可以防止抵赖的发生. 二.

  • Vue开发指南之重点知识梳理

    概述 如果您是Vue开发的新手,您可能已经听过很多关于它的专业术语了,例如:单页面应用程序.异步组件.服务器端呈现等. 另外您可能还经常听到和Vue一起提到的工具和库,如Vuex.Webpack.Vue CLI和Nuxt. 也许您在面对这些未知的术语和工具时会感到无助和绝望,没关系,您并不孤单,因为这是所有新手在初次接触Vue时都会有的感受. 但如果您试图要一次掌握所有这些内容,那么这些庞大的体系很可能会压垮你.为此,我在这里将为大家展示一个"知识图表",它包含了所有在专业Vue开发过

  • Android百度地图应用开发基础知识

    一.概述  这一章先来点有意思的百度地图应用示例,然后再分章详细介绍用C#开发Android App的各种基本技术.  本章以百度官网2016年1月发布的地图API(3.7.1版)为例,演示如何用C#和VS2015编写百度地图应用程序,这些示例程序既可以在Android 6.0的x86模拟器中运行,也可以发布到Android 4.0以上版本的手机中测试实际运行的效果.  1.下载官网提供的Demos  首先访问下面的网址: http://developer.baidu.com/map/ 打开网页

  • 使用Android开发接入第三方原生SDK实现微信登录

    微信开放平台 : https://open.weixin.qq.com/ 一.准备工作 : 1. Android Studio环境下:在build.gradle文件中,添加如下依赖即可: dependencies { implementation'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+' } 2. 在清单文件AndroidManifest.xml中加入权限: <uses-permission android:name="an

  • 常见Android编译优化问题梳理总结

    目录 编译常见问题 踩坑1 踩坑2 编译常见问题 在开发过程中,有碰到过一些由于编译优化导致的代码修改并不符合我们预期的情况.这也就是之前为什么我经常说编译产物其实是不太可以被信任的. 方法签名变更,底层仓库的方法变更但是上层模块并没有跟随一起重新编译导致的这个问题. 常量优化,将一些常量的调用点直接替换成常量的值. 删除空导包, 没有用的一些导包就会做一次剔除. 踩坑1 我们最近碰到一个 pipeline 相关而且很妖怪的问题.我们一个 pipeline 会检查apk产物中是否存在异常的方法调

  • 深入解读Android开发中Activity的生命周期

    什么是Activity        首先,Activity是Android系统中的四大组件之一,可以用于显示View.Activity是一个与用记交互的系统模块,几乎所有的Activity都是和用户进行交互的,但是如果这样就能说Activity主要是用来显示View就不太正确了. 在深入了解Activity之前,我们先要知道一下MVC设计模式,在JAVAEE 中MVC设计模式已经很经典了,而且分的也比较清晰了,但是在Android中,好多人对MVC在Android开发中的应用不是很清楚,下面我

随机推荐