精华内容
下载资源
问答
  • Android签名验证代码

    2018-04-17 16:49:05
    Android签名过程的验证过程,及其签名里面文件的生成过程的代码
  • 为各种使用第三方分享,推送,地图,对象存储等等需要填入各种格式的MD5,SHA签名而制作的工具,Android签名生成工具微信官方也有,不过只能生成MD5签名,格式也比较单一,该工具可以同时生成各种格式的MD5和SHA1...
  • Android签名生成工具

    2018-09-12 16:28:49
    各种格式的MD5,SHA签名而制作的工具,生成各种格式的MD5和SHA1签名
  • Android签名机制介绍

    2018-10-30 14:13:37
    一、Android签名机制--基础概念 1. 消息摘要算法 2. 非对称加密算法(RSA算法) 3. 数字签名 二、Android签名机制--APK签名过程 1. APK签名概述 2. APK签名相关的文件 3. 签名的过程(MANIFEST.MF) 4. 签名的过程...
  • Android签名工具下载,Android免费签名
  • 该APP提供了获取手机上已安装的所有应用的签名信息,并支持直接复制。
  • mac下android签名工具

    热门讨论 2015-02-27 18:28:14
    mac下android签名工具,为命令行有使用说明
  • Android签名工具(keytool)

    热门讨论 2014-03-11 11:05:09
    下载该文件后利用JDK中jarsigner工具生成签名文件 将位置定位在jdk的bin文件中,输入以下命名行: keytool -genkey -alias ChangeBackgroundWid get.keystore -keyalg RSA -validity 20000 -eystore ...
  • android签名获取工具

    2020-09-12 20:30:15
    android签名获取工具,用于获取androidAPP的签名,输入包名即可获取应用的签名。 android签名获取工具,用于获取androidAPP的签名,输入包名即可获取应用的签名。
  • android签名出错的解决方法 截图说明如何解决。
  • 1、 Android签名机制其实是对APK包完整性和发布机构唯一性的一种校验机制。 2、Android签名机制不能阻止APK包被修改,但修改后的再签名无法与原先的签名保持一致。 (除非拥有发布者的私钥)。 3、APK包加密的公钥就...

    Android生成签名文件对应用签名 & Android签名作用

    一、签名作用

    1、 Android签名机制其实是对APK包完整性和发布机构唯一性的一种校验机制。
    2、Android签名机制不能阻止APK包被修改,但修改后的再签名无法与原先的签名保持一致。
    (除非拥有发布者的私钥)。
    3、APK包加密的公钥就打包在APK包内,且不同的私钥对应不同的公钥。换句话言之,不同的私钥签名的APK公钥也必不相同。所以我们可以根据公钥的对比,来判断私钥是否一致。
    4、确定发布者身份,可以根据公钥来对APP进行更新,换句话说:可以防止APP被其他包名相同应用覆盖

    二、对应用进行签名

    1、

    在这里插入图片描述

    点击 Generate Signed Bundle / APK

    2、

    在这里插入图片描述

    点击 Create new

    3、

    在这里插入图片描述

    key store path : 要生成 .jks 文件的路径
    Alias : 别名
    Validity:有效年限
    下面一些: 姓名、组织机构、组织单位、城市、省、国家

    4、

    在这里插入图片描述

    点击 ok 后会弹出用这样一个弹窗 直接点击 ok ,然后在下一个页面点击 next 。进入步骤 5

    5、

    在这里插入图片描述

    至此,.jks 文件已经生成

    接下来就是进行打包时的签名配置,在 app --> build.gradle 中进行配置

    signingConfigs {//设置签名文件
            debug {
                storeFile file('../key/baiduMap.jks')
                storePassword '123456'
                keyAlias = 'key0'
                keyPassword '123456'
            }
            release {
                storeFile file('../key/baiduMap.jks')
                storePassword '123456'
                keyAlias = 'key0'
                keyPassword '123456'
                v1SigningEnabled true
                v2SigningEnabled true
            }
        }
        
        buildTypes {//设置build类型
            release {
                //是否优化zip
                zipAlignEnabled true
                // 移除无用的resource文件
                shrinkResources true
                //启用代码混淆
                minifyEnabled true
                //混淆规则配置文件
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
                //指明签名文件位置
                signingConfig signingConfigs.release
                buildConfigField "Boolean", "DEBUG_MODE", 'false'
            }
    
            debug {
                shrinkResources false
                minifyEnabled false
                zipAlignEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                signingConfig signingConfigs.debug
                buildConfigField "Boolean", "DEBUG_MODE", 'true'
            }
        }
    

    在发布过程中有些商店必须要使用 .keystore文件来进行签名,这时可以直接把 .jks 文件后缀直接更改为 .keystore 即可

    展开全文
  • Android 签名机制 v1、v2、v3

    千次阅读 2019-07-31 08:48:57
    什么是签名? 要想知道签名是什么,先来看为什么需要签名 ? 了解 HTTPS 通信的同学应该知道,在消息通信时,必须至少解决两个问题:一是确保消息来源的真实性,二是确保消息不会被第三方篡改。 在安装 APK 时,同样...

    什么是签名?

    要想知道签名是什么,先来看为什么需要签名 ?

    了解 HTTPS 通信的同学应该知道,在消息通信时,必须至少解决两个问题:一是确保消息来源的真实性,二是确保消息不会被第三方篡改。

    在安装 APK 时,同样需要确保 APK 来源的真实性,以及 APK 没有被第三方篡改。如何解决这两个问题呢?

    方法就是开发者对 APK 进行签名:在 APK 中写入一个「指纹」。指纹写入以后,APK 中有任何修改,都会导致这个指纹无效,Android 系统在安装 APK 进行签名校验时就会不通过,从而保证了安全性。

    要了解如何实现签名,需要了解两个基本概念:消息摘要、数字签名和数字证书。

    消息摘要(Message Digest)

    消息摘要(Message Digest),又称数字摘要(Digital Digest)或数字指纹(Finger Print)。简单来说,消息摘要就是在消息数据上,执行一个单向的 Hash 函数,生成一个固定长度的Hash值,这个Hash值即是消息摘要。

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

    • 无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。

    例如:应用 MD5 算法摘要的消息有128个比特位,用 SHA-1 算法摘要的消息最终有 160 比特位的输出,SHA-1 的变体可以产生 192 比特位和 256 比特位的消息摘要。一般认为,摘要的最终输出越长,该摘要算法就越安全。

    • 消息摘要看起来是「随机的」。

    这些比特看上去是胡乱的杂凑在一起的。可以用大量的输入来检验其输出是否相同,一般,不同的输入会有不同的输出,而且输出的摘要消息可以通过随机性检验。但是,一个摘要并不是真正随机的,因为用相同的算法对相同的消息求两次摘要,其结果必然相同;而若是真正随机的,则无论如何都是无法重现的。因此消息摘要是「伪随机的」。

    • 消息摘要函数是单向函数,即只能进行正向的信息摘要,而无法从摘要中恢复出任何的消息,甚至根本就找不到任何与原信息相关的信息。

    当然,可以采用强力攻击的方法,即尝试每一个可能的信息,计算其摘要,看看是否与已有的摘要相同,如果这样做,最终肯定会恢复出摘要的消息。但实际上,要得到的信息可能是无穷个消息之一,所以这种强力攻击几乎是无效的。

    • 好的摘要算法,没有人能从中找到「碰撞」。或者说,无法找到两条消息,使它们的摘要相同。

    虽然「碰撞」是肯定存在的(由于长明文生成短摘要的 Hash 必然会产生碰撞)。即对于给定的一个摘要,不可能找到一条信息使其摘要正好是给定的。

    正是由于以上特点,消息摘要算法被广泛应用在「数字签名」领域,作为对明文的摘要算法。著名的消息摘要算法有 RSA 公司的 MD5 算法和 SHA-1 算法及其大量的变体。

    SHA-256 是 SHA-1 的升级版,现在 Android 签名使用的默认算法都已经升级到 SHA-256 了。

    消息摘要的这种特性,很适合来验证数据的完整性。比如:在网络传输过程中下载一个大文件 BigFile,我们会同时从网络下载 BigFile 和 BigFile.md5,BigFile.md5 保存 BigFile 的摘要,我们在本地生成 BigFile 的消息摘要和 BigFile.md5 比较,如果内容相同,则表示下载过程正确。

    注意,消息摘要只能保证消息的完整性,并不能保证消息的不可篡改性。

    数字签名(Digital Signature)

    数字签名方案是一种以电子形式存储消息签名的方法。一个完整的数字签名方案应该由两部分组成:签名算法和验证算法。

    在讲数字签名之前,我们先简单介绍几个相关知识点:「公钥密码体制」、「对称加密算法」、「非对称加密算法」。

    公钥密码体制(public-key cryptography)

    公钥密码体制分为三个部分,公钥、私钥、加密解密算法,它的加密解密过程如下:

    • 加密:通过加密算法和公钥对内容(或者说明文)进行加密,得到密文。加密过程需要用到公钥。
    • 解密:通过解密算法和私钥对密文进行解密,得到明文。解密过程需要用到解密算法和私钥。注意,由公钥加密的内容,只能由私钥进行解密,也就是说,由公钥加密的内容,如果不知道私钥,是无法解密的。

    公钥密码体制的公钥和算法都是公开的(这是为什么叫公钥密码体制的原因),私钥是保密的。大家都以使用公钥进行加密,但是只有私钥的持有者才能解密。

    在实际 的使用中,有需要的人会生成一对公钥和私钥,把公钥发布出去给别人使用,自己保留私钥。目前使用最广泛的公钥密码体制是 RSA 密码体制。

    对称加密算法(symmetric key algorithms)

    在对称加密算法中,加密和解密都是使用的同一个密钥。因此对称加密算法要保证安全性的话,密钥要做好保密,只能让使用的人知道,不能对外公开。

    非对称加密算法(asymmetric key algorithms)

    在非对称加密算法中,加密使用的密钥和解密使用的密钥是不相同的。前面所说的公钥密码体制就是一种非对称加密算法,它的公钥和是私钥是不能相同的,也就是说加密使用的密钥和解密使用的密钥不同,因此它是一个非对称加密算法。

    RSA 简介

    RSA 密码体制是一种公钥密码体制,公钥公开,私钥保密,它的加密解密算法是公开的。 由公钥加密的内容可以并且只能由私钥进行解密,而由私钥加密的内容可以并且只能由公钥进行解密。也就是说,RSA 的这一对公钥、私钥都可以用来加密和解密,并且一方加密的内容可以由并且只能由对方进行解密。

    • 加密:公钥加密,私钥解密的过程,称为「加密」。

    因为公钥是公开的,任何公钥持有者都可以将想要发送给私钥持有者的信息进行加密后发送,而这个信息只有私钥持有者才能解密。

    • 签名: 私钥加密,公钥解密的过程,称为「签名」。

    它和加密有什么区别呢?因为公钥是公开的,所以任何持有公钥的人都能解密私钥加密过的密文,所以这个过程并不能保证消息的安全性,但是它却能保证消息来源的准确性和不可否认性,也就是说,如果使用公钥能正常解密某一个密文,那么就能证明这段密文一定是由私钥持有者发布的,而不是其他第三方发布的,并且私钥持有者不能否认他曾经发布过该消息。故此将该过程称为「签名」。

    数字签名

    事实上,任何一个公钥密码体制都可以单独地作为一种数字签名方案使用。

    如 RSA 作为数字签名方案使用时,可以定义如下:

    这种签名实际上就是用信源的私钥加密消息,加密后的消息即成了签体;而用对应的公钥进行验证,若公钥解密后的消息与原来的消息相同,则消息是完整的,否则消息不完整。

    它正好和公钥密码用于消息保密是相反的过程。因为只有信源才拥有自己地私钥,别人无法重新加密源消息,所以即使有人截获且更改了源消息,也无法重新生成签体,因为只有用信源的私钥才能形成正确地签体。

    同样信宿只要验证用信源的公钥解密的消息是否与明文消息相同,就可以知道消息是否被更改过,而且可以认证消息是否是确实来自意定的信源,还可以使信源不能否认曾经发送的消息。所以 这样可以完成数字签名的功能。

    但这种方案过于单纯,它仅可以保证消息的完整性,而无法确保消息的保密性。而且这种方案要对所有的消息进行加密操作,这在消息的长度比较大时,效率是非常低的,主要原因在于公钥体制的加解密过程的低效性。所以这种方案一般不可取。

    几乎所有的数字签名方案都要和快速高效的摘要算法(Hash 函数)一起使用,当公钥算法与摘要算法结合起来使用时,便构成了一种有效地数字签名方案。

    这个过程是:

    • 用摘要算法对消息进行摘要。
    • 再把摘要值用信源的私钥加密。

    通过以上两步得到的消息就是所谓的原始信息的数字签名,发送者需要将原始信息和数字签名一同发送给接收者。而接收者在接收到原始信息和数字签名后,通过以下 3 步验证消息的真伪:

    1. 先把接收到的原始消息用同样的摘要算法摘要,形成「准签体」。

    2. 对附加上的那段数字签名,使用预先得到的公钥解密。

    3. 比较前两步所得到的两段消息是否一致。如果一致,则表明消息确实是期望的发送者发的,且内容没有被篡改过;相反,如果不一致,则表明传送的过程中一定出了问题,消息不可信。

    这种方法使公钥加密只对消息摘要进行操作,因为一种摘要算法的摘要消息长度是固定的,而且都比较「短」(相对于消息而言),正好符合公钥加密的要求。这样效率得到了提高,而其安全性也并未因为使用摘要算法而减弱。

    综上所述,数字签名是 非对称加密技术 + 消息摘要 技术的结合。

    数字证书(Digital Certificate)

    通过数字签名技术,确实可以解决可靠通信的问题。一旦验签通过,接收者就能确信该消息是期望的发送者发送的,而发送者也不能否认曾经发送过该消息。

    大家有没有注意到,前面讲的数字签名方法,有一个前提,就是消息的接收者必须事先得到正确的公钥。如果一开始公钥就被别人篡改了,那坏人就会被你当成好人,而真正的消息发送者给你发的消息会被你视作无效的。而且,很多时候根本就不具备事先沟通公钥的信息通道。

    那么如何保证公钥的安全可信呢?这就要靠数字证书来解决了。

    数字证书是一个经证书授权(Certificate Authentication)中心数字签名的包含公钥拥有者信息以及公钥的文件。数字证书的格式普遍采用的是 X.509 V3 国际标准,一个标准的 X.509 数字证书通常包含以下内容:

    • 证书的发布机构(Issuer)

    该证书是由哪个机构(CA 中心)颁发的。

    • 证书的有效期(Validity)

    证书的有效期,或者说使用期限。过了该日期,证书就失效了。

    • 证书所有人的公钥(Public-Key)

    该证书所有人想要公布出去的公钥。

    • 证书所有人的名称(Subject)

    这个证书是发给谁的,或者说证书的所有者,一般是某个人或者某个公司名称、机构的名称、公司网站的网址等。

    • 证书所使用的签名算法(Signature algorithm)

    这个数字证书的数字签名所使用的加密算法,这样就可以使用证书发布机构的证书里面的公钥,根据这个算法对指纹进行解密。

    • 证书发行者对证书的数字签名(Thumbprint)

    也就是该数字证书的指纹,用于保证数字证书的完整性,确保证书没有被修改过。

    其原理就是在发布证书时,CA 机构会根据签名算法(Signature algorithm)对整个证书计算其 hash 值(指纹)并和证书放在一起,使用者打开证书时,自己也根据签名算法计算一下证书的 hash 值(指纹),如果和证书中记录的指纹对的上,就说明证书没有被修改过。

    可以看出,数字证书本身也用到了数字签名技术,只不过签名的内容是整个证书(里面包含了证书所有者的公钥以及其他一些内容)。与普通数字签名不同的是,数字证书的签名者不是随随便便一个普通机构,而是 CA 机构。这就好像你的大学毕业证书上签名的一般都是德高望重的校长一样。

    一般来说,这些 CA 机构的根证书已经在设备出厂前预先安装到了你的设备上了。所以,数字证书可以保证证书里的公钥确实是这个证书所有者的,或者证书可以用来确认对方的身份。可见,数字证书主要是用来解决公钥的安全发放问题。

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

    [外链图片转存失败(img-99hsDCJG-1564534236644)(https://raw.githubusercontent.com/jeanboydev/Android-ReadTheFuckingSourceCode/master/resources/images/android/basic/10_signature/01.png)]

    Android 中的签名方案

    Android 的签名方案,发展到现在,不是一蹴而就的。Android 现在已经支持三种应用签名方案:

    • v1 方案:基于 JAR 签名。
    • v2 方案:APK 签名方案 v2,在 Android 7.0 引入。
    • v3 方案:APK 签名方案 v3,在 Android 9.0 引入。

    v1 到 v2 是颠覆性的,为了解决 JAR 签名方案的安全性问题,而到了 v3 方案,其实结构上并没有太大的调整,可以理解为 v2 签名方案的升级版,有一些资料也把它称之为 v2+ 方案。

    因为这种签名方案的升级,就是向下兼容的,所以只要使用得当,这个过程对开发者是透明的。

    v1 到 v2 方案的升级,对开发者影响最大的,就是渠道签署的问题。在当下这个大环境下,我们想让不同渠道、市场的安装包有所区别,携带渠道的唯一标识,这就是我们俗称的渠道包。好在各大厂都开源了自己的签渠道方案,例如:Walle(美团)、VasDolly(腾讯)都是非常优秀的方案。

    APK 签名方案 v1

    签名工具

    Android 应用的签名工具有两种:jarsignerapksigner。它们的签名算法没什么区别,主要是签名使用的文件不同。

    • jarsigner:jdk 自带的签名工具,可以对 jar 进行签名。使用 keystore 文件进行签名。生成的签名文件默认使用 keystore 的别名命名。
    • apksigner:Android sdk 提供的专门用于 Android 应用的签名工具。使用 pk8、x509.pem 文件进行签名。其中 pk8 是私钥文件,x509.pem 是含有公钥的文件。生成的签名文件统一使用“CERT”命名。

    既然这两个工具都是给 APK 签名的,那么 keystore 文件和 pk8,x509.pem 他们之间是不是有什么联系呢?答案是肯定的,他们之间是可以转化的,这里就不再分析如何进行转化,网上的例子很多。

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

    签名过程

    首先我们任意选取一个签名后的 APK(Sample-release.APK)解压:

    META-INF 文件夹下有三个文件:MANIFEST.MFCERT.SFCERT.RSA。它们就是签名过程中生成的文件,姑且叫他们「签名三兄弟」吧,把它们搞清楚了,你就精通签名了。

    MANIFEST.MF

    该文件中保存的内容其实就是逐一遍历 APK 中的所有条目,如果是目录就跳过,如果是一个文件,就用 SHA1(或者 SHA256)消息摘要算法提取出该文件的摘要然后进行 BASE64 编码后,作为「SHA1-Digest」属性的值写入到 MANIFEST.MF 文件中的一个块中。该块有一个「Name」属性, 其值就是该文件在 APK 包中的路径。

    在这里插入图片描述

    CERT.SF

    • SHA1-Digest-Manifest-Main-Attributes:对 MANIFEST.MF 头部的块做 SHA1(或者SHA256)后再用 Base64 编码

    • SHA1-Digest-Manifest:对整个 MANIFEST.MF 文件做 SHA1(或者 SHA256)后再用 Base64 编码

    • SHA1-Digest:对 MANIFEST.MF 的各个条目做 SHA1(或者 SHA256)后再用 Base64 编码

    在这里插入图片描述

    对于 SHA1-Digest 值的验证可以手动进行,将 MANIFEST.MF 中任意一个块的内容复制并保存在一个新的文档中,注意文末需要加两个换行(这是由 signAPK 的源码决定的)

    在这里插入图片描述

    CERT.RSA

    这里会把之前生成的 CERT.SF 文件,用私钥计算出签名, 然后将签名以及包含公钥信息的数字证书一同写入 CERT.RSA 中保存。这里要注意的是,Android APK 中的 CERT.RSA 证书是自签名的,并不需要这个证书是第三方权威机构发布或者认证的,用户可以在本地机器自行生成这个自签名证书。Android 目前不对应用证书进行 CA 认证。

    • 什么是自签名证书?

    所谓自签名证书是指自己给自己颁发的证书,即公钥证书中 Issuer(发布者)和 Subject(所有者)是相同的。当然,APK 也可以采用由 CA 颁发私钥证书进行签名。采用非自签名时,最终 APK 的公钥证书中就会包含证书链,并且会存在多余一个证书,证书间通过 Issuer 与 Subject进行关联,Issuer 负责对 Subject 进行认证。当安装 APK 时,系统只会用位于证书链 中最底层的证书对 APK 进行校验,但并不会验证证书链的有效性。

    在 HTTPS 通信中使用自签名证书时浏览器的显示效果:

    CERT.RSA 文件中的内容:

    这里我们看到的都是二进制文件,因为 RSA 文件加密了,所以我们需要用 openssl 命令才能查看其内容:

    $ openssl pkcs7 -inform DER -in /<文件存放路径>/Sample-release_new/original/META-INF/CERT.RSA -text -noout -print_certs

    在这里插入图片描述

    综上所述,一个完整的签名过程如下所示:

    签名校验过程

    签名验证是发生在 APK 的安装过程中,一共分为三步:

    1. 检查 APK 中包含的所有文件,对应的摘要值与 MANIFEST.MF 文件中记录的值一致。

    2. 使用证书文件(RSA 文件)检验签名文件(SF 文件)没有被修改过。

    3. 使用签名文件(SF 文件)检验 MF 文件没有被修改过。

    综上所述,一个完整的签名验证过程如下所示:

    为什么使用这样的签名流程呢?

    我们假设一下,首先,如果你改变了 APK 包中的任何文件,那么在 APK 安装校验时,改变后的文件摘要信息与 MANIFEST.MF 的检验信息不同,于是验证失败,程序就不能成功安装。

    其次,如果你对更改过的文件相应的算出新的摘要值,然后更改 MANIFEST.MF 文件里面对应的属性值,那么必定与 CERT.SF 文件中算出的摘要值不一样,照样验证失败。

    最后,如果你还不死心,继续计算 MANIFEST.MF 的摘要值,相应的更改 CERT.SF 里面的值,那么数字签名值必定与 CERT.RSA 文件中记录的不一样,还是失败。

    那么能不能继续伪造数字签名呢?不可能,因为没有数字证书对应的私钥。

    APK 签名方案 v2

    APK 签名方案 v2 是一种全文件签名方案,该方案能够发现对 APK 的受保护部分进行的所有更改,从而有助于加快验证速度并增强完整性保证。

    v1 签名机制的劣势

    从 Android 7.0 开始,Android 支持了一套全新的 V2 签名机制,为什么要推出新的签名机制呢?通过前面的分析,可以发现 v1 签名有两个地方可以改进:

    • 签名校验速度慢

    校验过程中需要对apk中所有文件进行摘要计算,在 APK 资源很多、性能较差的机器上签名校验会花费较长时间,导致安装速度慢。

    • 完整性保障不够

    META-INF 目录用来存放签名,自然此目录本身是不计入签名校验过程的,可以随意在这个目录中添加文件,比如一些快速批量打包方案就选择在这个目录中添加渠道文件。

    为了解决这两个问题,在 Android 7.0 Nougat 中引入了全新的 APK Signature Scheme v2。

    v2 带来了什么变化?

    由于在 v1 仅针对单个 ZIP 条目进行验证,因此,在 APK 签署后可进行许多修改 — 可以移动甚至重新压缩文件。事实上,编译过程中要用到的 ZIPalign 工具就是这么做的,它用于根据正确的字节限制调整 ZIP 条目,以改进运行时性能。而且我们也可以利用这个东西,在打包之后修改 META-INF 目录下面的内容,或者修改 ZIP 的注释来实现多渠道的打包,在 v1 签名中都可以校验通过。

    v2 签名将验证归档中的所有字节,而不是单个 ZIP 条目,因此,在签署后无法再运行 ZIPalign(必须在签名之前执行)。正因如此,现在,在编译过程中,Google 将压缩、调整和签署合并成一步完成。

    v2 签名模式

    简单来说,v2 签名模式在原先 APK 块中增加了一个新的块(签名块),新的块存储了签名,摘要,签名算法,证书链,额外属性等信息,这个块有特定的格式,具体格式分析见后文,先看下现在 APK 成什么样子了。

    为了保护 APK 内容,整个 APK(ZIP 文件格式)被分为以下 4 个区块:

    • ZIP 条目的内容(从偏移量 0 处开始一直到“APK 签名分块”的起始位置)
    • APK 签名分块
    • ZIP 中央目录
    • ZIP 中央目录结尾

    其中,应用签名方案的签名信息会被保存在 区块 2(APK Signing Block)中,而区块 1(Contents of ZIP entries)、区块 3(ZIP Central Directory)、区块 4(ZIP End of Central Directory)是受保护的,在签名后任何对区块 1、3、4 的修改都逃不过新的应用签名方案的检查。

    签名过程

    从上面我们可以看到 v2 模式块有点类似于我们 META-INF 文件夹下的信息内容。那么对于上述当中摘要的信息又是怎么计算出来的呢。

    首先,说一下 APK 摘要计算规则,对于每个摘要算法,计算结果如下:

    • 将 APK 中文件 ZIP 条目的内容、ZIP 中央目录、ZIP 中央目录结尾按照 1MB 大小分割成一些小块。
    • 计算每个小块的数据摘要,数据内容是 0xa5 + 块字节长度 + 块内容。
    • 计算整体的数据摘要,数据内容是 0x5a + 数据块的数量 + 每个数据块的摘要内容

    总之,就是把 APK 按照 1M 大小分割,分别计算这些分段的摘要,最后把这些分段的摘要在进行计算得到最终的摘要也就是 APK 的摘要。然后将 APK 的摘要 + 数字证书 + 其他属性生成签名数据写入到 APK Signing Block 区块。

    签名校验过程

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

    其中 v2 签名机制是在 Android 7.0 以及以上版本才支持。因此对于 Android 7.0 以及以上版本,在安装过程中,如果发现有 v2 签名块,则必须走 v2 签名机制,不能绕过。否则降级走 v1 签名机制。
    v1 和 v2 签名机制是可以同时存在的,其中对于 v1 和 v2 版本同时存在的时候,v1 版本的 META_INF 的 .SF 文件属性当中有一个 X-Android-APK-Signed 属性:

    X-Android-APK-Signed: 2
    

    因此如果想绕过 v2 走 v1 校验是不行的。

    v2 对多渠道打包的影响

    之前的渠道包生成方案是通过在 META-INF 目录下添加空文件,用空文件的名称来作为渠道的唯一标识。但在新的应用签名方案下 META-INF 已经被列入了保护区了,向 META-INF 添加空文件的方案会对区块 1、3、4 都会有影响。

    可以参考:美团解决方案

    APK 签名方案 v3

    Android 9.0 中引入了新的签名方式,它的格式大体和 v2 类似,在 v2 插入的签名块(Apk Signature Block v2)中,又添加了一个新快(Attr块)。

    在这个新块中,会记录我们之前的签名信息以及新的签名信息,以密钥转轮的方案,来做签名的替换和升级。这意味着,只要旧签名证书在手,我们就可以通过它在新的 APK 文件中,更改签名。

    v3 签名新增的新块(attr)存储了所有的签名信息,由更小的 Level 块,以链表的形式存储。

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

    这个过程有点类似 CA 证书的证明过程,已安装的 App 的旧签名,确保覆盖安装的 APK 的新签名正确,将信任传递下去。

    签名校验过程

    Android 的签名方案,无论怎么升级,都是要确保向下兼容。

    在引入 v3 方案后,Android 9.0 及更高版本中,可以根据 APK 签名方案,v3 -> v2 -> v1 依次尝试验证 APK。而较旧的平台会忽略 v3 签名并尝试 v2 签名,最后才去验证 v1 签名。

    整个验证的过程,如下图:

    需要注意的是,对于覆盖安装的情况,签名校验只支持升级,而不支持降级。也就是说设备上安装了一个使用 v1 签名的 APK,可以使用 v2 签名的 APK 进行覆盖安装,反之则不允许。

    我的 GitHub

    github.com/jeanboydev

    我的公众号

    欢迎关注我的公众号,分享各种技术干货,各种学习资料,职业发展和行业动态。

    Android 波斯湾

    技术交流群

    欢迎加入技术交流群,来一起交流学习。

    QQ 技术交流群
    微信技术交流群

    参考资料

    展开全文
  • Android签名替换工具

    2016-02-25 11:49:31
    为apk添加签名以及替换签名,好用的工具
  • Android 签名打包

    万次阅读 2018-06-05 01:14:24
    Android 要求所有已安装的应用程序都使用数字证书做数字签名,数字证书的私钥由开发者持有。Android 使用证书作为标识应用程序作者的一种方式,证书不需要由证书认证中心签名,使用自制签名证书。Android 系统不会...


    什么是签名?

    Android 要求所有已安装的应用程序都使用数字证书做数字签名,数字证书的私钥由开发者持有。

    Android 使用证书作为标识应用程序作者的一种方式,证书不需要由证书认证中心签名,使用自制签名证书。

    Android 系统不会安装或运行没有正确签名的应用,此规则适用于任何地方运行的Android系统。因此在真机或模拟器上运行或者调试应用前,必须为其设置好签名。

    两种签名:

    1、调试模式下签名   (sdk 为应用主动生成一个签名证书,调试模式下签名的应用不能对外发布,因为由构建工具创建的证书是不安全的,应用商店不接受调试证书签名的apk)

    2、公布模式下签名 (需要生成自己的证书)

    注:给自己开发的app签名,就代表着我们自己的版权,之后要进行升级,也必须要使用相同的签名才可以,签名代表着自己的身份(即 keystore,是一个包括私人秘钥集合的二进制文件),创建的keystore 多个app可以使用同一签名。


    为什么要有签名?

    开发Android的人众多,完全有可能把雷鸣、包名命名成相同的名字,需要签名来区分,由于开发商可能通过使用相同包名来混淆替换已经安装的程序,签名可以保证相同名字,但是签名不同的包不被替换。

    签名机制在Android应用和框架中有着十分重要的作用,例如:Android系统禁止跟新安装签名不一致的apk,若应用需要使用system权限,必须保证apk签名与framwork签名一致。


    为什么要这么做?

    •  应用程序升级 -  当发布应用的更新时,如果想染给用户无缝的升级到新版本,需要继续使用相同的某个或某套证书来签名更新包,当系统安装应用的更新时,它会比较现在的版本和新版本的证书,如果证书吻合,包括证书数据和顺序都吻合,那么系统允许更新,如果新版本所做的签名不是匹配的,那么将需要给用起一个不同的包名 - 在这种情况下,用户相当于安装了一个完全新的程序。
    • 用用程序模块化 - Android允许相同证书签名的应用程序运行在相同的进程中,此时系统会将它们作为耽搁应用程序对待,在这种方式中,可以按模块化的凡事部署应用,用户可以根据需要独立的跟新每一个模块。
    • 代码、数据的授权共享 - Android提供模式匹配的权限控制机制,因此一个应用可以暴露功能给另一个用指定证书签名的签名的应用,通过用相同证书签名多个应用,以及使用模式匹配的权限检查,应用程序可以以安全的方式共享代码和数据。


    公钥和私钥的概念

    在现代密码体制中加密和解密是采用不同的秘钥(公开秘钥),也就是公开秘钥算法(也叫非对称算法、双钥算法),每个通信方均需要两个秘钥,即公钥和私钥,这两个秘钥可以互为加解密,公钥是公开的,不要保密,而私钥是由个人自己持有,并且必须妥善保管和注意保密的。


    证书的概念

    数字证书是由证书认证机构(CA)对证书申请者真实身份验证之后,用CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机构的公章)后形成的数字文件。CA完成签发证书后,会将证书发布在CA的证书库(目录服务器)中,任何人都可以查询和下载,因此数字证书和公钥一样是公开的,实际上数字证书就是经过CA认证的公钥。

    原则:

    • 一个公钥对应一个私钥
    • 秘钥对中,让大家都知道的是公钥,不告诉大家只有自己知道的是私钥
    • 如果用其中一个秘钥可以解密,那么该数据必须是对应的秘钥进行的加密
    • 非对称秘钥密码的主要应用就是公钥加密和公钥认证,而公钥加密的过程和公钥认证的过程是不一样的

    例:两个用户 A 和 B ,A要把一段明文通过双钥加密的技术发送给 B , B有一对公钥和私钥,那么加密解密过程如下

        1. B 将他的公钥传送给A

        2. A 用 B 的公钥加密的他的消息,然后传送给 B

        3. B 用他的私钥解密 A 的消息


    调试版相关问题

    证书到期问题:用来签署apk调试的自签名证书有效期365天,到期后只需删除该debug.keystore文件。

    文件存储位置 --- OS 和 Linux 系统:~/.android /

                         --- windows 7, 8, 10 : C:\Users\<user>\.android\


    发布版的签名

    1. 手动生成签名的 apk (使用 Android Studio 手动生成签名的 apk,每次发布不同版本的时候都需要手动生成一次,比较麻烦)

    步骤如下:

        1> 在Android Studio菜单栏中,Build --> Generate Signed APK

            

        2>如果你已经有一个秘钥库,请转到步骤4,如果你想创建一个新的秘钥库,单击新建

            

        注:Key store path: 秘钥库存储位置

               Key store password:秘钥库安全密码

               Key alias:秘钥标识名称

               Key password: 秘钥安全密码

               秘钥安全密码应当与秘钥库安全密码不同


        3>创建新的秘钥库如下图

             

        

        注:秘钥的有效时间设置以年为单位,应至少为25年,以便您可以在应用的整个生命周期内使用相同的秘钥签署应用更新

        Certificate 部分是为证书输入关于您自己的信息,此信息不会显示在应用中,但会作为apk的一部分包含在您的证书中

        Firstand Last Name 秘钥颁发者姓名

        OrganizationalUnit 秘钥颁发者组织单位

        Organization 组织

        Cityor Locality 城市

        State or Province 市或洲

        CountryCodeXX 国家代码


        4>在生成签名apk窗口中,选择秘钥库、秘钥,并输入两个密码(如果是新创秘钥,这些字段会自动填充)然后单击xiayi

        

        


        5>选择签署的apk目的地,构建类型,产品风味,单击完成


        

        

        APK Destination Folder 为签署的APK选择一个目的地


        Build Type 选择构建的类型(两种类型调试和正式


        Flavors 选择产品风味(即我们平时所说的发布平台,Android将为选择的每个产品风味生成单独的apk

        Signature Versions 签名版本勾选 Android7.0中引入了APKSignature Scheme v2

        

        说明:v1:应用是通过zip条目进行验证,这样apk签署后可进行许多修改 - 可以移动甚至重新压缩文件

        v2:验证压缩文件的所有字节,而不是单个zip条目,签名后无法再更改


    2. 配置 build.gradle 文件自动签名apk

    步骤如下:

        1>Android Studio 菜单栏 File --> Project Structure ( 快捷键 ctrl+alt +shift +s)

        2>选中app这个module,然后切换到singning标签栏,然后点击添加,生成release签名信息,点击ok

        

        3>切换到Build Types 标签,将Signing config 选为“release”,即将刚刚生成的release签名信息配置进去

        

        

        4>随后我们可以看到app这个module的build.gradle文件多出了如下部分代码

          


        5>然后执行菜单栏的“build --> clean Project”



    6>生成release版本的apk,在命令行terminal输入gradlew assembleRelease (AS已经将命令行Terminal 继承到了软件当中)运行成功的话,效果如下:



    7> 生成签名好的文件在如下位置:




    展开全文
  • Android应用签名获取工具,解压缩后内为APK文件,输入目标包名获取应用签名,方便快捷。希望能帮助到大家
  • 在eclipse中签名的方法是:选中工程,邮件选择”export-android-export android application”, 1、方式1:通过Android Studio进行签名: 选中app这个module,选择菜单栏”Build-Generate signed apk”: 上图中...
  • Android签名与校验过程详解

    万次阅读 2017-11-30 16:12:12
    目 录  一、签名与校验原理概要 2 ... Android签名与校验过程详解 一、签名与校验原理概要 1、数字签名简介 在日常生活中,签名通常被做为个人身份的凭证。当一份文件上有某个人的签名时,便相信此份文件确实由此

     

    目 录

     

    一、签名与校验原理概要    2

    1、数字签名简介    2

    2、CMS简介    2

    二、signapk工具签名过程    4

    三、OTA校验过程    6

     

     

    Android签名与校验过程详解

    一、签名与校验原理概要

    1、数字签名简介

    在日常生活中,签名通常被做为个人身份的凭证。当一份文件上有某个人的签名时,便相信此份文件确实由此人审阅过了。与之类似,在数字安全领域中,数字签名也起着类似的作用。

    首先,数字签名证实了一份数字信息确实来自于某个实体。因为基于非对称加密的原理,用私钥加密的消息只能用对应的公钥解密,反之亦然。如图 1 所示,签名是由该实体的私钥生成,而私钥只由签名方持有。因此在图 2 中,只能用签名方的公钥对签名进行解密。而当解密成功时,便可相信是签名方生成了此消息。

    其次,数字签名可以确保消息在传递过程中未被篡改。如图 1 所示,数字签名是由特定算法的哈希值加密而来。使用 MD5、SHA 等哈希算法可以确保消息哈希值的唯一性。因此在图 2 中,可以通过用同样的算法重新计算消息的哈希值,与签名中的哈希值对比。若结果一致,则可信任该消息在发出后未被篡改。

        图一、数字签名的生成过程 图二、数字签名的校验过程

    2、CMS简介

    由于我们的签名规范源于CMS,这里简单介绍下。

    CMS(Crypto Message Syntax)是由互联网工程任务组(IETF)制定的安全消息规范 (RFC 5652)。该规范定义多种消息格式,分别用于对任意消息进行数字签名、哈希、认证和加密。

    该规范所规定的数字签名格式可以包含如下内容:哈希值生成算法、签名方的数字证书(包含签名方的公钥)、签名方的基本信息、消息原文、签名等。对比上一节数字签名的生成和验证过程可以发现,CMS 规范所规定格式已经包含了数字签名所有必需的信息。

    同时,对于开发者而言,可以利用开源工具方便的生成 CMS 格式的数字签名。例如 Linux 下的 openssl 命令以及 Java 的开源类库 BouncyCastle,都提供了针对 CMS 格式数字签名的生成和验证功能。

    由于我们使用的签名工具signapk使用java接口所写,我们所关心的就是如何用Java实现CMS数字签名的生成与验证。签名过程大同小异,在代码实现上也是如此。这里生成数字签名的实例在网上摘录如下:

    【生成CMS数字签名】

    public String sign(X509CertificateHolder signCert, KeyPair signKP) {

    List certList = new ArrayList();

    certList.add(signCert);

    Store certs = new JcaCertStore(certList);

    CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes());

    CMSSignedDataGenerator gen = new CMSSignedDataGenerator();

    ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(signKP.getPrivate());

    gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(

    new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, signCert));

    gen.addCertificates(certs);

    CMSSignedData sigData = gen.generate(msg, true);

    String signature = new String(sigData.getEncoded());

    Return signature;

    }

    如上所展示的是为"Hello World"这一字符串生成 CMS 数字签名的过程。其中 certs 代表签名方的证书,signKP.getPrivate() 代表签名方的私钥,SHA1withRSA 代表消息的哈希算法是 SHA1,生成公钥私钥的算法是 RSA。这些要素与前文介绍的数字签名的生成过程相吻合。最后得到的 signature 就是 CMS 格式的数字签名字符串。对比signapk.java中的writeSignatureBlock函数,在操作步骤上基本一致。

    最后值得注意的是 gen.generate(msg, true),这里的第二个参数代表是否将消息原文封装到签名当中。若这一参数为 false,通常称生成的是 detached signature,表示签名和消息是分开存放的。

    【验证CMS数字签名】

    public String verify(String signature){

    CMSSignedData s = new CMSSignedData(signature.getBytes());

    CertStore certs = s.getCertificatesAndCRLs("Collection", "BC");

    SignerInformationStore signers = s.getSignerInfos();

    boolean verified = false;

    for (Iterator i = signers.getSigners().iterator(); i.hasNext(); ) {

    SignerInformation signer = (SignerInformation) i.next();

    Collection<? extends Certificate> certCollection =

    certs.getCertificates(signer.getSID());

    if (!certCollection.isEmpty()) {

    X509Certificate cert =

    (X509Certificate) certCollection.iterator().next();

    if (signer.verify(cert.getPublicKey(), "BC")) {

    verified = true;

    }

    }

    }

    CMSProcessable signedContent = s.getSignedContent() ;

    byte[] originalContent = (byte[]) signedContent.getContent();

    return new String(originalContent);

    }

    这里展示了如何验证在上述生成的数字签名。因为CMS数字签名支持多个实体对消息进行签名,因此这里可以对每个签名方逐一进行验证。签名方的证书已经包含在签名中,而证书包含验证签名所需的签名方的公钥。recoveryverifier.cpp中的verify_file函数解析步骤可以类比上述内容。

    二、signapk工具签名过程

    signapk对zip包的签名指令如下:

    java-Xmx1024m -jarout/host/linux-x86/framework/signapk.jar -w ./testkey.x509.pem./testkey.pk8 update.zip update_signed.zip


    从指令中可以看出,真个签名过程是基于signapk.jar工具包进行的,对应源码位于build\tools\signapk\SignApk.java中,具体流程可以从main函数分析,这里只关注比较核心的部分——CMSSigner类中的write函数,该函数中包含对update_signed.zip包中CERT.SF、CERT.RSA、MANIFEST.MF等的签名与生成过程(下面是网友总结,与自己对代码的理解基本吻合):

    1. 对jar包中的各文件进行sha1hash,生成manifest对象,除META-INF文件夹下MANIFEST.MF、CERT.SF、CERT.RSA、com/android/otacert外。

    Manifest manifest = addDigestsToManifest(inputJar, hash);

    2. 将manifest对象中描述的各文件copy到新jar包中;

    copyFiles(manifest, inputJar, outputJar, timestamp, 0);

    3. 如果-w整包签,则将证书.x509.pem复制到META-INF/com/android/otacert,并在manifest对象中增加META-INF/com/android/otacert的SHA1摘要;

    addOtacert(outputJar, publicKeyFile, timestamp, manifest, hash);

    这里是在signapk.java中main函数中获取传参后根据是否有"-w"所决定的:

            while (argstart < args.length && args[argstart].startsWith("-")) {

    if ("-w".equals(args[argstart])) {

    signWholeFile = true;

    ++argstart;

    } else if

            .....

    这里如果看到"-w"参数,则将signWholeFil标志设置为true。接着走如下流程:

            if (signWholeFile) {

    SignApk.signWholeFile(inputJar, firstPublicKeyFile,

    publicKey[0], privateKey[0], outputFile);

    } else {

    JarOutputStream outputJar = new JarOutputStream(outputFile);

     

    // For signing .apks, use the maximum compression to make

    // them as small as possible (since they live forever on

    // the system partition). For OTA packages, use the

    // default compression level, which is much much faster

    // and produces output that is only a tiny bit larger

    // (~0.1% on full OTA packages I tested).

    outputJar.setLevel(9);

     

    Manifest manifest = addDigestsToManifest(inputJar, hashes);

    copyFiles(manifest, inputJar, outputJar, timestamp, alignment);

    signFile(manifest, inputJar, publicKey, privateKey, outputJar);

    outputJar.close();

    }

            .....

    跟踪signWholeFile函数会走到上述提到的CMSSigner类中的write函数中来(这里从代码上不知为何并没有走通,应该和CMS协议规范有关吧。不过,本人通过打log追踪,具体流程确实如上所说)。可以看出,signWholeFile为false的情况下,会走else分支,这里并没有addOtacert操作。

    4. 将manifest对象写入新jar包中META-INF/MANIFEST.MF文件;

    现在开始的操作主要就是在signFile函数中完成的。该步骤具体内容如下:

        // MANIFEST.MF

    JarEntry je = new JarEntry(JarFile.MANIFEST_NAME);

    je.setTime(timestamp);

    outputJar.putNextEntry(je);

    manifest.write(outputJar);

    5. 生成签名文件META-INF/CERT.SF和CERT.RSA;

         for (int k = 0; k < numKeys; ++k) {

    // CERT.SF / CERT#.SF

    je = new JarEntry(numKeys == 1 ? CERT_SF_NAME :

    (String.format(CERT_SF_MULTI_NAME, k)));

    je.setTime(timestamp);

    outputJar.putNextEntry(je);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    writeSignatureFile(manifest, baos, getDigestAlgorithm(publicKey[k]));

    byte[] signedData = baos.toByteArray();

    outputJar.write(signedData);

     

    // CERT.{EC,RSA} / CERT#.{EC,RSA}

    final String keyType = publicKey[k].getPublicKey().getAlgorithm();

    je = new JarEntry(numKeys == 1 ?

    (String.format(CERT_SIG_NAME, keyType)) :

    (String.format(CERT_SIG_MULTI_NAME, k, keyType)));

    je.setTime(timestamp);

    outputJar.putNextEntry(je);

    writeSignatureBlock(new CMSProcessableByteArray(signedData),

    publicKey[k], privateKey[k], outputJar);

    }

    对于CERT.SF文件,是对manifest中(每一项文件名称、sha1摘要)做sha1摘要, 生成新的Manifest对象,具体见writeSignatureFile函数;而CERT.RSA文件,privateKey对signedData加密生成签名,然后把签名和公钥证书一起保存到CERT.RSA中,是PKCS#7格式签名/加密信息(对CERT.SF进行SHA1withRSA,并将证书.pem附在其中)。具体见writeSignatureBlock函数。

    7. 如果-w整包签,则在jar/zip文件

    找到'End of central directory signature'

    (一般zip如果无Comment length时,EOCD标记距尾部22Bytes)

    [End of central directory record]格式

    Offset Bytes Description[18]

    0 4End of central directory signature | 核心目录结束标记(0x06054b50)

    4 2Number of this disk | 当前磁盘编号

    6 2Disk where central directory starts | 核心目录开始位置的磁盘编号

    8 2Number of central directory records on this disk | 该磁盘上所记录的核心目录数量

    10 2Total number of central directory records | 核心目录结构总数

    12 4Size of central directory (bytes) | 核心目录的大小

    16 4Offset of start of central directory,relative to start of archive | 核心目录开始位置相对于archive开始的位移

    20 2Comment length (n)

    注释长度

    22 nComment(注释内容)

    在其后写入Archive Comment:

    signature_start = Comment_Length - len('signed by SignApk') - 1

    (PKCS#7_SIG)是对对整个zip包(从ZIP头到<EOCD.CommentLength>之前)数据生成sha1,再对sha1用私钥加密生成签名放在公钥证书尾部整个Comment为PKCS#7格式(类似于CERT.RSA,只不过是对整个zip包数据做签名)

    OTA包校验时也是先对ZIP包数据生成sha1,然后从ZIP尾部EOCD中取出Comment中的签名数据(SHA1WithRSA),用公钥解开再和sha1对比,一致则验证通过,具体实现在recovery\verifier.cpp中的verify_file()函数中。

    三、OTA校验过程

    OTA在升级前,拿到一个ota zip包之后,在真正安装前会对其进行签名校验。具体流程在recovery/install.zpp文件中,主要涉及到load_keys以及verify_file函数。load_keys主要是用来load /res/keys文件,并从中解析出公钥publicKey。下面重点关注verify_file:

    首先声明的是,在整个校验期间系统并没有加压ota的zip包,是直接根据zip的压缩格式中的关键标志进行对zip包的解析。函数开头有说明:

    // An archive with a whole-file signature will end in six bytes:

    //

    // (2-byte signature start) $ff $ff (2-byte comment size)

    //

    // (As far as the ZIP format is concerned, these are part of the

    // archive comment.) We start by reading this footer, this tells

    // us how far back from the end we have to start reading to find

    // the whole comment.

    简单来说就是:一个被整包签名做的压缩文件总是使用6个特定byte结尾,具体格式为:

    (2-byte signature start) $ff $ff (2-byte comment size)

    函数开始开头就会从zip文件结尾,根据这6个byte进行其他标志bytes的查找个定位。具体code不再列出,本人根据各标志位位置,对ota的某zip包做了一个解析,相关签名部分以十六进制显示如下:

    经过verify_file函数定位解析后,主要标志位置大致如下图所示:

    清楚了上面的zip文件中签名所存放的位置后,接着就可以将Signature块取出来:

    size_t signature_size = signature_start - FOOTER_SIZE;//1720-6=1714

    if (!read_pkcs7(eocd + eocd_size - signature_start, signature_size, &sig_der,

    &sig_der_length)) {

    LOGE("Could not find signature DER block\n");

    return VERIFY_FAILURE;

    }

    接着就可以根据签名时的加密算法进行校验了,我们的加密算法是RSA,这里只看RSA分支部分:

            // The 6 bytes is the "(signature_start) $ff $ff (comment_size)" that

    // the signing tool appends after the signature itself.

    if (pKeys[i].key_type == Certificate::RSA) {

    if (sig_der_length < RSANUMBYTES) {

    // "signature" block isn't big enough to contain an RSA block.

    LOGI("signature is too short for RSA key %zu\n", i);

    continue;

    }

     

    if (!RSA_verify(pKeys[i].rsa, sig_der, RSANUMBYTES,

    hash, pKeys[i].hash_len)) {

    LOGI("failed to verify against RSA key %zu\n", i);

    continue;

    }

     

    LOGI("whole-file signature verified against RSA key %zu\n", i);

    free(sig_der);

    return VERIFY_SUCCESS;

    } else if

    分析上述代码可知,整个过程分两个步骤:

    1、判断sig_der_length 长度是否比RSANUMBYTES(签名部分中的publicKey内容)要大,如果小于,则提示" signature is too short for RSA key ",继续校验其他publicKey,如果没有其他的publicKey,或者其他的publicKey也是这种情况,则continue到校验失败;

    2、通过函数RSA_verify函数对RSANUMBYTES进行真正的校验,校验通过则成功,否则失败。

    展开全文
  • Flutter Android 签名打包

    千次阅读 2020-03-11 14:03:18
    文章目录查看APP包的签名Flutter 配置Android 签名创建 keystore引用应用程序中的keystoregradle中配置签名构建一个发布版apk(打包)在设备上安装发行版APK 查看APP包的签名 为了检查flutter打包的签名信息, 找到...
  • Android签名证书 keystore jks pem x509

    万次阅读 2019-10-24 15:01:26
    Android签名证书 背景 因业务需求,经常与系统厂商打交道,大多需要厂商开放root权限 目前获取系统权限的总结有三种方式(均有实际应用) platform签名 root固件 (有su) 调用厂商封装好的系统权限的sdk 后两者调试比较...
  • Android签名证书:jks和keystore

    千次阅读 2020-06-30 17:34:19
    jks是在android studio里面生成的签名证书。 keystore是eclipse里面生成的。 两者在使用方式上没有什么区别,但是在算法上有一点点区别。 jks转keystore 很多第三方市场,我们上传apk的时候,他们只支持keystore,...
  • mac android app 签名工具

    2018-04-28 14:32:49
    mac版android apk签名工具包,实现加密apk二次签名打包,简单好用又方便!
  • Android签名证书生成

    万次阅读 2018-08-18 12:27:02
    写在前面:正式打包发布Android的apk应用,需要先选择或新建一个数字证书,即keystore文件,生成数字证书的常用方法有两:一是利用eclipse生成,二是在命令行中生成,下面我们来介绍如何在命令行中生成Android的数字...
  • Android 签名文件

    千次阅读 2018-09-17 15:10:44
    由于现在开发android JDK基本都是用的1.7及以上,所以低版本的JDK的就不记录了。 首先找到一个文件夹,以下操作都在同一个文件夹内,这样是为了更加方便,当然也可以...一、创建签名文件 命令: keytool -genkey ...
  • Android电子签名手写板

    2019-03-07 22:07:02
    一个手写板功能,实现电子签名功能。可以把签名内容变为bitmap方便存储,支持一键清除手写板View上面签名
  • Android签名验证——Hook签名第一步

    千次阅读 2019-08-29 18:20:12
    网上虽然很多Hook Android App 签名的方法,例如: 一键绕过App签名验证 一键破解APK签名校验 ...这篇文章先讲第一个问题——Android签名验证 由于网上相关文章比较多,这里就不赘术,仅提供核心代码 能研究这个...
  • android MD5签名生成器

    2017-11-16 11:25:28
    android MD5签名生成器,查看签名后的app的md5 码,直接安装,填写包名即可
  • 丨版权说明 :《Android签名生成和Android签名格式转换工具(MD5和SHA1签名)》于当前CSDN博客和乘月网属同一原创,转载请说明出处,谢谢。为各种使用第三方分享,推送,地图,对象存储等等需要填入各种格式的MD5,SHA...
  • Android签名与风险分析

    千次阅读 2016-06-13 19:21:12
    Android 系统中,所有安装到系统的应用程序都必有一个数字证书,这个数字证书就是这个应用的签名。此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个 permission的protectionLevel为...
  • Android 你了解Android签名文件吗?

    万次阅读 2016-11-14 15:45:44
    签名介绍Android签名相信大家经常会遇到的,当我们做好一款APP准备发布的时候我们就需要一个realese的key文件给我们这个app签名.那我们没有指定的APK是不是就没有签名呢,?并不是,所有的APK都是有签名的,如果没有...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 89,804
精华内容 35,921
关键字:

android签名