基本签名流程: 验证签名java -jar apksigner.jar verify -v inputName.apk 读签名文件:keytool.exe -list -v -keystore ./meme.jks -storepass 123456 ? ?从输出中拿到别名 对齐包:zipalign.exe -p -v 4 input.apk output.apk ? 按4字节将输入包对齐,防止后面签名出错 V2签名命令:java.exe -jar apksigner.jar sign -verbose --ks SVC-release-key.keystore --v1-signing-enabled false --v2-signing-enabled true --v3-signing-enabled false --ks-pass pass:20160523 --ks-key-alias svckey(别名) --key-pass pass:123456 --out outputName.apk --in inputName.apk
读取apk包的MD5值 java -jar CheckAndroidSignature.jar app-release_signed.apk {"ret":0,"msg":"","isV1OK":false,"isV2":true,"isV2OK":true,"isV3":false,"isV3OK":false,"keystoreMd5":"b72b16517a4a98e9bb93b4f86a74f0ae"}
v1签名: v1签名会校验 APK 中每个文件的合法性,但并不包含META-INF目录中的文件,而且也不能保护 APK 的某些部分,例如 ZIP 元数据。 v2签名: 与v1签名对压缩包内的部分文件进行保护不同,v2签名是一种全文件签名方案,使用 方案 v2 进行签名时,会在 APK 文件中插入一个 APK 签名分块,该分块位于“ZIP 中央目录”部分之前并紧邻该部分。在“APK 签名分块”内,v2 签名和签名者身份信息会存储在 APK 签名方案 v2 分块中 渠道包方案: 早期使用的在zip文件的注释部分写入渠道信息的方案,对于v2签名显然是不可行的,会导致签名验证不通过。但是v2签名引入了“签名块”,“签名块”中包含了很多“ID-值”对,我们可以添加一个自己的“ID-值”对,值就是渠道信息,要获取渠道的时候通过我们自定义的ID去找到就行了,v2签名后walle的新版本就是基于这个原理。
v3签名: 对于一款上架的 App,当签名失效之后,我们只能被迫换签名,此时因为签名校验无法通过,就会导致旧用户无法覆盖安装。这些历史用户唯一的选择,就是卸载后重新安装,这个代价显然是太大了。 Android 9 支持 APK 密钥轮转,这使应用能够在 APK 更新过程中更改其签名密钥。
Proof-of-rotation 结构位于signed data的“其他属性”中,ID 为0x3ba06f8c,其中包含一个单链表,每个节点都包含用于为之前版本的应用签名的签名证书。该单链表按版本排序,最旧的签名证书对应于根节点。系统会让每个节点中的证书为列表中的下一个证书签名,从而为每个新密钥提供证据来证明它应该像旧密钥一样可信。
1>创建证书链 1. 创建新的可用证书链: java -jar apksigner.jar rotate --out /path/to/new/file --old-signer --ks release.jks \ ? ? --new-signer --ks release2.jks
2. 向证书链中添加新的证书: java -jar apksigner.jar rotate --in /path/to/existing/lineage --out /path/to/new/file \ ? ? --old-signer --ks release2.jks --new-signer --ks release3.jks
3. 创建新的证书,设置新证书是否使用原来证书的数据: java -jar apksigner.jar rotate --out /path/to/new/file --old-signer --ks release.jks \ ? ? --set-installed-data true --set-shared-uid true --set-permission true --set-rollback false \ ? ? --set-auth true --new-signer --ks release2.jks
1. 使用唯一秘钥进行签名: java -jar apksigner.jar sign --ks release.jks --in app.apk --out app-signed.apk
4. 使用两个签名文件进行签名: java -jar apksigner.jar sign --ks release.jks --next-signer --ks magic.jks app.apk
8. 使用签名证书链对apk进行签名: java -jar apksigner.jar sign --ks release.jks --next-signer --ks release2.jks \ ? ? --lineage /path/to/signing/history/lineage app.apk ?? ? ?? ? 命令验证: 1>使用两个证书生成证书链:成功 java -jar apksigner.jar rotate -verbose --out linechain --old-signer --ks whale-yh.jks --ks-pass pass:soundWhale --ks-key-alias whale --key-pass pass:soundWhale --new-signer --ks ijiami.keystore --ks-pass pass:ijiami --ks-key-alias ijiami --key-pass pass:ijiami 2>向旧的证书链中添加新的证书,生成新的证书链:成功 java -jar apksigner.jar rotate -verbose --in linechain --out outlinechain --old-signer --ks ijiami.keystore --ks-pass pass:ijiami --ks-key-alias ijiami --key-pass pass:ijiami --new-signer --ks three-hj.jks --ks-pass pass:ijiami --ks-key-alias key0 --key-pass pass:ijiami?? ?
3>使用包含两个证书的证书链进行签名:成功(签名成功,覆盖安装成功) java -jar apksigner.jar sign -verbose --ks whale-yh.jks --ks-pass pass:soundWhale --ks-key-alias whale --key-pass pass:soundWhale --next-signer --ks ijiami.keystore --ks-pass pass:ijiami --ks-key-alias ijiami --key-pass pass:ijiami --lineage linechain --v1-signing-enabled true --v2-signing-enabled true --v3-signing-enabled true --in snjr_signed_signed.apk --out app-signed-all.apk 4>使用包含三个证书的证书链进行签名:成功 (签名成功,覆盖安装成功),起始节点,请使用根证书 java -jar apksigner.jar sign -verbose --ks whale-yh.jks --ks-pass pass:soundWhale --ks-key-alias whale --key-pass pass:soundWhale --next-signer --ks three-hj.jks --ks-pass pass:ijiami --ks-key-alias key0 --key-pass pass:ijiami --lineage outlinechain --v1-signing-enabled true --v2-signing-enabled true --v3-signing-enabled true --in snjr_signed_signed.apk --out app-signed-all.apk
5>使用最新包单证书签名的包覆盖多证书包:成功(签名成功,覆盖安装成功) java -jar apksigner.jar sign -verbose --ks three-hj.jks --ks-pass pass:ijiami --ks-key-alias key0 --key-pass pass:ijiami ?--v1-signing-enabled true --v2-signing-enabled true --v3-signing-enabled false --in snjr_signed_signed.apk --out app-Three.apk
|