Android apk签名原理

一、为什么要签名?

确保Apk来源的真实性。
确保Apk没有被第三方篡改。

二、什么是签名?

在Apk中写入一个“指纹”。指纹写入以后,Apk中有任何修改,都会导致这个指纹无效,Android系统在安装Apk进行签名校验时就会不通过,从而保证了安全性。

三、apk组成

  • dex:最终生成的Dalvik字节码。

  • res:存放资源文件的目录。

  • asserts:额外建立的资源文件夹。

  • lib:如果存在的话,存放的是ndk编出来的so库。

  • META-INF:存放签名信息

  • MANIFEST.MF(清单文件):其中每一个资源文件都有一个SHA-256-Digest签名,MANIFEST.MF文件的SHA256(SHA1)并base64编码的结果即为CERT.SF中的SHA256-Digest-Manifest值。

  • CERT.SF(待签名文件):除了开头处定义的SHA256(SHA1)-Digest-Manifest值,后面几项的值是对MANIFEST.MF文件中的每项再次SHA256并base64编码后的值。

  • CERT.RSA(签名结果文件):其中包含了公钥、加密算法等信息。首先对前一步生成的MANIFEST.MF使用了SHA256(SHA1)-RSA算法,用开发者私钥签名,然后在安装时使用公钥解密。最后,将其与未加密的摘要信息(MANIFEST.MF文件)进行对比,如果相符,则表明内容没有被修改。

  • androidManifest:程序的全局清单配置文件。

  • resources.arsc:编译后的二进制资源文件。

四、apk签名校验

1.签名和校验的主要过程

签名就是在摘要的基础上再进行一次加密,对摘要加密后的数据就可以当作数字签名。

2.签名过程
  • 计算摘要:通过Hash算法提取出原始数据的摘要。
  • 计算签名:再通过基于密钥(私钥)的非对称加密算法对提取出的摘要进行加密,加密后的数据就是签名信息。
  • 写入签名:将签名信息写入原始数据的签名区块内。
3.校验过程
  • 首先用同样的Hash算法从接收到的数据中提取出摘要。
  • 解密签名:使用发送方的公钥对数字签名进行解密,解密出原始摘要。
  • 比较摘要:如果解密后的数据和提取的摘要一致,则校验通过;如果数据被第三方篡改过,解密后的数据和摘要将会不一致,则校验不通过。
4.数字证书

如何保证公钥的可靠性呢?答案是数字证书,数字证书是身份认证机构(Certificate Authority)颁发的,包含了以下信息:

  • 证书颁发机构
  • 证书颁发机构签名
  • 证书绑定的服务器域名
  • 证书版本、有效期
  • 签名使用的加密算法(非对称算法,如RSA)公钥等

接收方收到消息后,先向CA验证证书的合法性,再进行签名校验。

Apk的证书通常是自签名的,也就是由开发者自己制作,没有向CA机构申请。Android在安装Apk时并没有校验证书本身的合法性,只是从证书中提取公钥和加密算法,这也正是对第三方Apk重新签名后,还能够继续在没有安装这个Apk的系统中继续安装的原因。

5.keystore和证书格式

keystore文件中包含了私钥、公钥和数字证书。根据编码不同,keystore文件分为很多种,Android使用的是Java标准keystore格式JKS(Java Key Storage),所以通过Android Studio导出的keystore文件是以.jks结尾的。

6.jarsigner和apksigner的区别

Android提供了两种对Apk的签名方式,一种是基于JAR的签名方式,另一种是基于Apk的签名方式,它们的主要区别在于使用的签名文件不一样:jarsigner使用keystore文件进行签名;apksigner除了支持使用keystore文件进行签名外,还支持直接指定pem证书文件和私钥进行签名。

在签名时,除了要指定keystore文件和密码外,也要指定alias和key的密码,这是为什么呢?
keystore是一个密钥库,也就是说它可以存储多对密钥和证书,keystore的密码是用于保护keystore本身的,一对密钥和证书是通过alias来区分的。所以jarsigner是支持使用多个证书对Apk进行签名的,apksigner也同样支持。

猜你喜欢

转载自blog.csdn.net/weixin_42600398/article/details/125042210