安卓v3签名,安卓v1v2v3签名区别

  安卓v3签名,安卓v1v2v3签名区别

  Android v1,v2,v3签名详细讲解Android签名机制。安卓签名是什么?了解HTTPS通信的同学都知道,消息通信至少要解决两个问题:一是保证消息来源的真实性,二是保证消息不会被第三方篡改。

  同样,在安装apk时,也需要确保apk来源的真实性,以及apk没有被第三方篡改。为了解决这个问题,Android官方要求开发者对apk进行签名,签名就是对apk进行加密的过程。要理解如何实现签名,需要知道两个基本概念:消息摘要、数字签名和数字证书。

  消息摘要,也称为数字摘要或数字指纹。简单来说,消息摘要就是对消息数据进行单向哈希函数,生成固定长度的哈希值,这就是消息摘要。

  上面提到的加密哈希函数就是消息摘要算法。它具有以下特点:

  无论输入消息有多长,计算出的消息摘要的长度总是固定的。例如,MD5算法总结的报文有128位,SHA-1算法总结的报文最终有160位输出。SHA-1的变体可以生成192比特和256比特的消息摘要。一般来说,摘要的最终输出越长,抽象算法就越安全。摘要看起来很“随意”。这些比特似乎是随机混合在一起的。大量的输入可以用来检查它们的输出是否相同。一般不同的输入会有不同的输出,输出的总结消息可以通过随机性测试。然而,摘要并不是真正随机的,因为如果使用相同的算法提取相同的消息两次,结果将是相同的。如果真的是随机的,无论如何都是无法复制的。因此,消息摘要是伪随机的。消息汇总功能是一个单向功能,即只能正面汇总信息,而不能从汇总中恢复任何消息,甚至根本找不到任何与原始信息相关的信息。当然,我们可以使用暴力攻击的方法,即尝试每一个可能的信息,计算它的摘要,看它是否与现有的摘要相同。如果我们这样做,我们最终将恢复摘要消息。但实际上要获取的信息可能是无限条消息中的一条,所以这种强大的攻击几乎无效。好的总结算法,没人能从中发现“碰撞”。或者,两条消息都找不到,以至于它们的摘要都是一样的。虽然“碰撞”是肯定的(因为长明文和短摘要生成Hash,必然会发生碰撞)。也就是说,对于一个给定的摘要,不可能找到一条信息使摘要恰好是给定的摘要。由于上述特点,消息摘要算法作为一种明文摘要算法被广泛应用于“数字签名”领域。众所周知的消息摘要算法包括RSA公司的MD5算法和SHA-1算法及其大量变种。SHA-256是SHA-1的升级版,现在安卓签名使用的默认算法已经升级到了SHA-256。

  因为消息摘要具有这种特性,所以非常适合验证数据的完整性。比如网络传输时下载了一个BigFile BigFile,我们会同时从网络下载BigFile和BigFile.md5,BigFile.md5会保存BigFile的摘要。我们会在本地生成Bigfile的消息摘要,并与Bigfile.md5进行比较,如果内容相同,说明下载过程是正确的。

  数字签名的作用是保证信息传输的完整性,验证发送者的身份,防止交易中的抵赖。数字签名技术用发送方的私钥对摘要信息进行加密,与原文一起传输给接收方。只有使用发送方的公钥,接收方才能解密加密的摘要信息,然后使用哈希函数生成接收到的原文的摘要信息,并与解密的摘要信息进行比较。如果相同,说明接收到的信息是完整的,在传输过程中没有被修改;否则意味着信息被修改过,所以数字签名可以验证信息的完整性。

  比如RSA作为数字签名方案时,其使用过程如下:这个签名实际上是用信源的私钥对消息进行加密,加密后的消息成为签名人;相应的公钥用于验证。如果由公钥解密的消息与原始消息相同,则该消息是完整的,否则,该消息是不完整的。

  RSA只是使用公钥加密实现消息保密的反向过程。因为只有源有自己的私钥,其他人无法重新加密源消息,即使有人截获并更改了源消息,也无法重新生成签名人,因为只有源的私钥才能形成正确的签名人。

  同样,目的地只要验证由源的公钥解密的消息是否与明文消息相同,就可以知道消息是否被篡改过,也可以验证消息是否真的来自预定的源,这样源就无法否认发送出去的消息。从而完成数字签名的功能。

  但是这种方案过于简单,它只能保证消息的完整性,而不能保证消息的机密性。而且这种方案需要对所有消息进行加密,在消息长度较大的情况下效率非常低。主要原因在于公钥系统的加解密过程效率低下。因此,这种方案一般不可取。

  几乎所有的数字签名方案都必须与快速高效的哈希算法(哈希函数)一起使用。当公钥算法与哈希算法相结合时,就构成了一个有效的数字签名方案。

  证书可以通过数字签名技术真正解决可靠通信的问题。一旦验证通过,接收者就可以确定消息是由预期的发送者发送的,并且发送者不能否认消息被发送。

  大家有没有注意到,上面提到的数字签名方法有一个前提,就是消息的接收方必须事先得到正确的公钥。如果公钥一开始就被篡改了,坏人会被你当成好人,真正发消息的人发的消息会被你当成无效。而且,在很多情况下,事先没有传递公钥的信息通道。

  那么如何保证公钥的安全性和可信性呢?这将通过数字证书来解决。

  数字证书是由证书认证中心数字签名的文件,包含公钥和公钥所有者的信息。数字证书的格式一般采用国际标准X.509v3,一个标准的X.509数字证书通常包含以下内容:

  证书颁发者:哪个机构(CA中心)颁发了证书。证书的有效期:证书的有效期,或使用期限。在该日期之后,证书将失效。证书所有者的公钥:证书所有者想要发布的公钥。证书所有者(主体)名称:这个证书是发给谁的,或者是证书的所有者,通常是某个人或某个公司的名称、某个组织的名称、该公司的网址等。用于证书的签名算法:用于该数字证书的数字签名的加密算法,以便可以根据该算法使用证书颁发机构颁发的证书中的公钥来解密指纹。证书颁发者的数字签名:数字证书的哈希值(指纹),用于保证数字证书的完整性,保证证书未被修改。数字证书的原理是证书颁发时,CA机构会根据签名算法计算出它的整个证书的哈希值(指纹)并和证书放在一起。当用户打开证书时,他还根据签名算法计算证书的哈希值(指纹)。如果与证书中记录的指纹相匹配,则说明证书没有被修改过。

  可以看出,数字证书本身也使用了数字签名技术,但签名的内容是整个证书(包含证书所有者的公钥和一些其他内容)。与普通的数字签名不同,数字证书的签署者不仅仅是一个普通的机构,而是一个CA机构。

  综上所述,数字签名和签名验证的一般流程如下图所示:

  Android打包流程整个Android打包流程如下图所示:

  编译步骤:

  1.打包资源文件,生成R.java文件打包资源的工具是aapt(Android资产打包工具)(e:\ documents \ Android \ SDK \ build-tools \ 25 . 0 . 0 \ aapt . exe)。

  在这个过程中,会编译项目中的AndroidManifest.xml文件和布局文件xml,然后生成相应的R.java。另外,AndroidManifest.xml会被aapt编译成二进制。

  存储在APP的res目录下的资源,在APP打包之前大多会编译成二进制文件,每个这样的文件都会被赋予一个资源id。对于这类资源的访问,通过资源id访问应用层代码。在编译Android的过程中,aapt工具会编译资源文件,生成一个resource.arsc文件,相当于一个文件索引表,记录了很多与资源相关的信息。

  2.在处理aidl文件并生成相应Java文件的过程中使用的工具是AIDL(Android Interface Definition Language),即Android界面描述语言(e:\ documents \ Android \ SDK \ build-tools \ 25 . 0 . 0 \ aidl . exe)。

  Aidl工具解析接口定义文件,然后生成相应的Java代码接口供程序调用。如果项目中不使用aidl文件,可以跳过这一步。

  3.编译项目的源代码以生成类文件。项目中的所有Java代码,包括Java和。aidl文件,将被编译成。类文件,生成的类文件将位于项目的bin/classes目录下。

  4.转换所有类文件并生成classes.dex文件。dx工具生成可以被Android系统的Dalvik虚拟机执行的classes.dex文件。该工具位于(e:\ documents \ Android \ SDK \ build-tools \ 25 . 0 . 0 \ dx . bat)。

  图书馆和。任何第三方的类文件都将被转换成。德克斯文件。dx工具的主要工作是将Java字节码转换成Dalvik字节码,压缩常量池,消除冗余信息。

  5.打包生成APK文件所有未编译的资源,比如images和assets目录下的资源(这类文件是一些原始文件,打包时不会被APP编译,而是直接打包到APP里。对于这类资源文件的访问,应用层代码需要通过文件名来访问);编译资源和。dex文件将被打包成最终版本。apkbuilder工具生成的apk文件。

  打包工具apkbuilder位于android-sdk/tools目录中。apkbuilder是一个脚本文件,它实际上调用了(e:\ documents \ Android \ SDK \ tools \ lib)文件中的com . Android . SDK lib . build . apkbuildermain类。

  6.签署APK文件。APK文件生成后,必须先进行签名,然后才能安装到设备上。

  在开发过程中,主要使用两种签名密钥库。一个是调试用的debug.keystore,主要用于调试。直接在Eclipse或者Android Studio运行后,就是手机上运行的debug.keystore。

  另一个是用于发布正式版本的keystore。

  7.对齐签名的apk文件。如果您发布的APK是官方版本,则必须对齐APK。使用的工具是zip align(e:\ documents \ Android \ SDK \ build-tools \ 25 . 0 . 0 \ zip align . exe)。

  对齐的主要过程是将apk包中的所有资源文件从文件开始偏移4字节的整数倍,这样通过内存映射访问APK文件的速度会更快。对齐的目的是减少运行时内存的使用。

  从上图可以看出,签名发生在打包过程的倒数第二步,签名针对的是现有的apk包,不会影响我们写的代码。事实确实如此。Android一般的签名原理是计算未签名apk中所有文件的hash,然后保存(MANIFEST。MF),然后计算这些hash的hash并保存(CERT。SF),然后计算hash,再用上面生成的密钥库中的私钥加密保存(CERT。RSA)。

  Android签名方案Android系统从诞生到现在的1.0版本,经历了三代应用签名方案,即v1、v2、v3方案。

  V1方案:基于JAR签名。V2方案:APK签名方案v2,在Android 7.0中引入。V3方案:APK签名方案v3,在Android 9.0中引入。其中v1到v2是颠覆性的,主要是解决JAR签名方案的安全问题,但是到了v3方案,没有太大的结构调整,可以理解为v2签名方案的升级版。

  从v1升级到v2对开发者影响最大的,就是渠道签约的问题。V2的招牌也是让不同渠道和市场的安装包不一样,并带有渠道的独特logo,也就是俗称的渠道包。好在各大厂商都开放了自己的签约渠道方案,比如Walle(美团)、VasDolly(腾讯),都是很优秀的方案。

  V1签名工具

  Android有两个签名工具:jarsigner和apksigner。他们的签名算法没什么区别,主要是签名用的文件不一样。它们的区别如下:

  Jarsigner:jdk自己的签名工具,可以给jar签名。使用密钥库文件进行签名。默认情况下,生成的签名文件以密钥库的别名命名。apsigner:Android SDK为Android应用程序提供的签名工具。使用pk8,x509.pem文件进行签名。其中pk8是私钥文件,x509.pem是包含公钥的文件。生成的签名文件统一用“CERT”命名。既然这两个工具是为APK签名的,那么keystore文件和pk8,x509.pem之间有什么联系吗?答案是肯定的,它们是可以转化的,这里就不分析它们是如何转化的了。网上有很多例子。

  还有一个知识点需要注意。如果我们查看密钥库文件的内容,我们会发现它包含MD5和SHA1摘要,这是密钥库文件中私钥的数据摘要。这些信息也是我们在申请很多开发平台账号时需要填写的信息。

  签名过程

  首先,我们随机选择一个签名的APK(样本发布。APK)对其进行解压缩,我们将得到如下图所示的文件。

  可以发现META-INF文件夹中有三个文件:MANIFEST。MF,CERT。SF和CERT。RSA它们是在签名过程中生成的文件,它们的作用如下。

  显化。中频

  这个文件中保存的内容实际上是逐个遍历APK的所有条目。如果是目录,跳过它。如果是文件,用SHA1(或SHA256)消息摘要算法提取文件的摘要,然后用BASE64编码,作为“SHA1摘要”属性的值写入清单中的一个块。MF文件。这个块有一个“Name”属性,它的值是APK包中文件的路径。

  打开清单。MF文件,包含以下内容:

  证明合格的芬兰

  打开证书。包含以下内容的SF文件:

  SHA1-digest-MANIFEST-main-attributes:对清单头中的块执行SHA1(或SHA256)。MF然后用Base64编码。SHA1摘要清单:为整个清单生成sha1(或SHA256)。MF文件,然后用Base64编码。SHA1文摘:为每个清单条目创建sha1(或SHA256)。MF然后用Base64编码。证明合格的南非共和国(Republic of South Africa)

  计算先前生成的证书的签名。SF文件,然后将签名和包含公钥信息的数字证书写入CERT。RSA并保存它。应该注意的是。Android APK中的RSA证书是自签名的,它不需要第三方权威机构颁发或认证的证书。用户可以在他们的本地机器上生成这个自签名证书。目前安卓对应用证书不进行CA认证。打开证书。包含以下内容的RSA文件:

  我们在这里看到的都是二进制文件。因为它们是用RSA加密的,所以我们需要使用openssl命令来查看它们的内容,如下所示。

  [普通]查看普通副本

  $opensslpkcs7-informDER-in/文件存储路径/sample-release _ new/original/meta-INF/cert . RSA-text-noout-print _ certs复制代码。执行上述命令后,您将得到以下内容:

  签名过程如下:

  计算每个原始文件的SHA-1摘要并写入清单。MF;计算整个清单的SHA-1汇总。MF文件并将其写入CERT。SF;计算清单中每个区块的SHA-1汇总。MF并将其写入CERT。SF;计算整个证书的摘要。SF文件,并使用开发者的私钥计算摘要的签名;将签名和开发者证书(X.509)写入CERT。南非共和国(Republic of South Africa)

  总而言之,一个完整的签名流程如下:

  签名验证

  签名验证在APK安装期间进行,分为三个步骤:

  检查APK中包含的所有文件,对应的汇总值与清单中记录的值一致。MF文件。使用证书文件(RSA文件)验证签名文件(SF文件)未被修改。使用签名文件(SF文件)验证MF文件未被修改。总而言之,一个完整的签名验证过程如下:

  V1签名的问题

  验证速度慢:需要计算汇总,验证apk中的每个文件。如果文件很多,验证时间会很长。完整性不足:V1签名只会验证Zip文件中的部分文件,比如META-INFO文件夹不会参与验证。

  V2签名APK签名方案V2是一个全文件签名方案,它可以发现对APK的受保护部分所做的所有改变,从而有助于加速验证和增强完整性保证。通过前面的分析,我们可以发现v1签名可以在两个方面进行改进:

  签名验证速度慢。在验证过程中,需要对apk中的所有文件进行汇总。在APK资源多、性能差的机器上进行签名验证需要很长时间,导致安装速度慢。完整性保证不足META-INF目录用于存储签名。自然,这个目录本身不包括在签名验证过程中。你可以随意添加文件到这个目录。例如,一些快速批量打包方案选择将通道文件添加到该目录中。为了解决这两个问题,在Android版本中引入了新的APK签名方案v2。

  V2的改进

  因为在v1中只验证一个ZIP条目,所以在APK签名后可以进行许多修改——您可以移动甚至重新压缩文件。事实上,这就是编译过程中使用的ZIPalign工具的作用。它用于根据正确的字节限制调整ZIP条目,以提高运行时性能。而且我们还可以用这个东西来修改打包后META-INF目录下的内容,或者修改ZIP的注释,实现多路打包,这些都可以在v1签名中验证。

  V2签名将验证存档中的所有字节,而不是单个ZIP条目,因此签名后无法运行ZIPalign(必须在签名前执行)。正因为如此,现在谷歌在编译的过程中,把压缩、调整、签名合二为一,一步到位。

  V2签名

  V2签名俱乐部在APK街区的基础上增加了一个新街区(签名街区)。新块存储诸如签名、摘要、签名算法、证书链和附加属性等信息。该块具有特定的格式。最终签名APK实际上有四个块:头文件区、V2签名块、中央目录和尾部。下图显示了V1签名和V2签名的组成。

  整个签名块的格式如下:

  块的大小,以字节为单位(不包括此字段)(uint64)“ID-值”对序列,带有uint 64长度前缀:块的大小,以字节为单位-与多个“ID-值”对中的第一个字段(uint 64)Magic“APK签名块42”(16字节)相同,APK

  带长度前缀的签名数据,包括digests序列、X.509证书序列、附加属性序列带长度前缀的签名(带长度前缀)序列公钥(SubjectPublicKeyInfo,ASN.1 DER form)值带长度前缀的可能包含多个签名人,因为Android允许多个签名。综上所述:一个签名块可以包含多个ID-value,APK的签名信息将存储在ID为0x7109871a的键值对中。他的内容可以包含多个签名者的签名信息,每个签名信息包含签名数据、签名和公钥,其中签名数据主要存储抽象序列、证书链和附加属性,签名包含多个签名算法计算的签名值,公钥代表签名者的公钥,在验证时用来验证签名。

  签名过程

  首先,我们来谈谈APK总结的计算规则。对于每种总结算法,计算结果如下:

  把APK的ZIP条目、ZIP中心目录和ZIP中心目录末尾的内容按照1MB的大小分成一些小块。计算每个小块的数据汇总,数据内容为0xa5块字节长度块内容。计算整体数据汇总,数据内容是0x5a数据块的个数,每个数据块的汇总内容。简而言之,按照1M的大小划分APK,分别计算这些段的汇总,最后计算这些段的汇总得到最终的汇总,也就是APK的汇总。然后由APK的抽象数字证书的其他属性生成的签名数据被写入APK签名块。

  签名验证过程

  接下来,我们来看看v2签名的验证过程。整体大概流程如下图所示。

  其中,只有Android 7.0及以上版本支持v2签名机制。所以对于Android 7.0及以上版本,在安装过程中,如果发现v2签名块,必须采取v2签名机制,不能绕过。否则,v1签名机制将降级。v1和v2签名机制可以同时存在,当v1和v2版本同时存在时,在。v1版本META_INF的SF文件属性。

  x-Android-APK-签名:2

  以前的通道包生成方案是在META-INF目录中添加一个空文件,并使用空文件的名称作为通道的唯一标识。但是,在新的应用程序签名方案下,META-INF已被列入保护区,在META-INF中添加空文件的方案将影响1、3和4块。

  我怎么知道有没有V2的签名?

  根据Zip文件格式的规则,我们可以找到中心目录区的起始位置。从起始位置读回这16个字节,判断这16个字节的值是否为‘Apk Sig Block 42’。如果是,那就对应着幻数,说明有V2的签名。这是解析V2签名块的后续过程。

  V3签名新版本V3签名基于v2,仍然采用检查整个压缩包的验证方式。不同的是,可以在签名部分添加一个新的证书(Attr块)。在这个新块中,我们以前的签名信息和新的签名信息都会被记录下来,签名会被密钥轮的方案替换和升级。这意味着只要旧的签名证书在手,我们就可以通过它来更改新APK文件中的签名。

  v3签名的新块(attr)存储所有的签名信息,由一个较小级别的块以链表的形式存储。

  每个节点都包含用于对应用程序的前一版本进行签名的签名证书,最旧的签名证书对应于根节点。系统将让每个节点中的证书签署列表中的下一个证书,从而为每个新密钥提供证据来证明它应该和旧密钥一样可信。

  签名验证过程

  Android的招牌方案,无论怎么升级,都是为了保证向后兼容。所以在引入v3方案后,在Android 9.0及以后的版本中,可以尝试按照APK签名方案,v3-v2-v1依次验证APK。旧平台会忽略v3签名,并在验证v1签名之前尝试v2签名。验证的整个过程如下:

  需要注意的是,在覆盖安装的情况下,签名验证只支持升级,而不支持降级。也就是说,在设备上安装了一个署名为v1的APK,署名为v2的APK可以用来掩护安装;否则是不允许的。

  版权归作者所有:原创作品来自博主mb6214323b59a49,转载请联系作者获得授权,否则将追究法律责任。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: