Android签名的过程
Android对apk签名过程
Apk解压后的结构:
会生成一个META-INF的文件夹存放签名相关的数据:MANIFEST.MF WUBA_KEY.RSA WUBA_KEY.SF。此三个文件都是我们对unsigin.apk签名时生成的。
- SHA1:安全哈希算法,对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要。
作用:
- 完整性,签过名后的Apk无法进行增删改,不然其签名都会不一样
- 自我校验,因为签过名后的Apk里有公钥,可以对其Apk进行自我校验,所以只需要Apk文件,在Android系统里就可以完成Apk的校验
- 并行性,校验可以并行进行,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 |
- signapk.jar是Android源码包中的一个签名工具
- 通过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 |
- -alias 后面跟的是别名这里是alias_name
- -keyalg 是加密方式这里是RSA
- -validity 是有效期这里是20000
- -keystore 就是要生成的keystore的名称这里是app.keystore
使用jarsigner对unsign.apk进行签名:
1 | jarsigner -verbose -keystore app.keystore -signedjar app_signed.apk app.apk alias_name |
- -keystore: keystore的名称
- -signedjar app_signed.apk: 指定签名后生成的APK名称
- app.apk: 目标APK
修改Keystore的密码的影响
使用keytool生成的keystore文件,我们称之为证书文件,里面存有用于签名apk的公钥及私钥,为了其安全,keystore有其自己本身的密码:
- storepass 指定密钥库的密码(获取keystore信息所需的密码)
- keypass 指定别名条目的密码(私钥的密码,即加密私钥的密码)
而我们可以修改keystore文件的storepass和keypass两种密码,都不影响对apk的签名,也不出现签名的apk不相同,因为keystore里面所包含的公钥和私钥是没有变化的。
keystore内部的信息是不会变化的:
1 | - XXX.Keystore的信息: |