Android签名的过程

Android对apk签名过程

Apk解压后的结构:

会生成一个META-INF的文件夹存放签名相关的数据:MANIFEST.MF WUBA_KEY.RSA WUBA_KEY.SF。此三个文件都是我们对unsigin.apk签名时生成的。

  1. SHA1:安全哈希算法,对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要。

作用:

  1. 完整性,签过名后的Apk无法进行增删改,不然其签名都会不一样
  2. 自我校验,因为签过名后的Apk里有公钥,可以对其Apk进行自我校验,所以只需要Apk文件,在Android系统里就可以完成Apk的校验
  3. 并行性,校验可以并行进行,WUBA_KEY.RSA对WUBA_KEY.SF的校验与WUBA_KEY.SF对MANIFEST.MF校验可以并行执行

Android系统签验证机制

系统验证流程刚好与签名过程相反:

了解签名流程后,能做的事情

打批量包

为了区分不同的渠道用于统计分析,apk里需要内置携带一个渠道号,各种方式的比较:

位置经历的过程特点
渠道号放在代码里编译代码,编译res资源,编译Manifest文件,签名,生成Apk非常慢,安全
放在res资源里编译res资源,编译Manifest文件,签名,生成Apk很慢,安全
放在AndroidManifest.xml文件里编译Manifest文件,签名,生成Apk慢,安全
放在asserts资源里签名,生成Apk快,安全
放在签名相关的META-INF文件夹里生成Apk非常快,不安全,可被修改

签名认证

目的:防止apk被别人反编译,或者防止so文件被直接使用
方案:由于Apk里携带了公钥,可以在so里,进行公钥对比,判断当前执行环境是不是在Apk里面。

Keystore文件生成过程

由上面的签名过程得知,签名过程,需要有公钥和私钥,所以签名方法:

1
java -jar signapk.jar testkey.x509.pem testkey.pk8 update.apk update_signed.apk
  1. signapk.jar是Android源码包中的一个签名工具
  2. 通过signapk.jar这个可执行jar包,以“testkey.x509.pem”这个公钥文件和“testkey.pk8”这个私钥文件对“update.apk”进行签名,签名后的文件保存为“update_signed.apk”

而对应用App,我们是使用java里的命令:jarsigner。使用jarsigner要先生成keystore文件,使用如下:

1
keytool -genkey -v -keystore app.keystore -alias alias_name -keyalg RSA -validity 20000
  1. -alias 后面跟的是别名这里是alias_name
  2. -keyalg 是加密方式这里是RSA
  3. -validity 是有效期这里是20000
  4. -keystore 就是要生成的keystore的名称这里是app.keystore

使用jarsigner对unsign.apk进行签名:

1
jarsigner -verbose -keystore app.keystore -signedjar app_signed.apk app.apk alias_name
  1. -keystore: keystore的名称
  2. -signedjar app_signed.apk: 指定签名后生成的APK名称
  3. app.apk: 目标APK

修改Keystore的密码的影响

使用keytool生成的keystore文件,我们称之为证书文件,里面存有用于签名apk的公钥及私钥,为了其安全,keystore有其自己本身的密码:

  1. storepass 指定密钥库的密码(获取keystore信息所需的密码)
  2. keypass 指定别名条目的密码(私钥的密码,即加密私钥的密码)

而我们可以修改keystore文件的storepass和keypass两种密码,都不影响对apk的签名,也不出现签名的apk不相同,因为keystore里面所包含的公钥和私钥是没有变化的。

keystore内部的信息是不会变化的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- XXX.Keystore的信息:
- Keystore 类型: JKS
- Keystore 提供者: SUN
- 您的 keystore 包含 1 输入
- 别名名称: XXXX
- 创建日期: XXXX
- 项类型: PrivateKeyEntry
- 认证链长度: 1
- 认证 [1]:
- 所有者:CN=XXX, OU=XXX, O=XXX, L=XXX, ST=XXX, C=XXX
- 签发人:CN=XXX, OU=XXX, O=XXX, L=XXX, ST=XXX, C=XXX
- 序列号:XXX
- 有效期: XXX
- 证书指纹:
- MD5:XXX
- SHA1:XXX
- 签名算法名称:SHA1withRSA
- 版本: 3

参考

  1. Android系统代码签名验证机制的实现及安全性分析
  2. Android签名总结
感谢您的阅读,本文由 刘阳 版权所有。如若转载,请注明出处:刘阳(https://handsomeliuyang.github.io/2016/06/13/%E6%97%A5%E5%B8%B8%E5%AD%A6%E4%B9%A0/2016-04-14-Android%E7%AD%BE%E5%90%8D%E7%9A%84%E8%BF%87%E7%A8%8B/
58同城Hybrid框架的点点滴滴
React实现MergeRequest管理