文章大綱:
- Android 為什么要簽名
- keystore的生成
- Android 怎么簽名
- 查看 apk 是否簽名
- 查看 Apk 的MD5值以及MD5不顯示時的解決辦法
Android 為什么要簽名
在安裝 apk 時,需要確保 apk 來源的真實性,以及 apk 沒有被第三方篡改。為了解決這一問題,Android官方要求開發者對 apk 進行簽名,所謂的簽名就是對apk進行加密的過程。
keystore的生成:
在簽名之前要生成 keystore 文件來存儲密鑰
(1)分階段生成:
keytool -genkey -alias yushan(別名) -keypass yushan(別名密碼) -keyalg RSA(算法) -keysize 1024(密鑰長度) -validity 365(有效期,天單位) -keystore 指定路徑/yushan.keystore(指定生成證書的位置和證書名稱) -storepass 123456(獲取keystore信息的密碼)
回車輸入相關信息即可;
keytool -genkey -alias test -keypass testmima -keyalg RSA -keysize 1024 -validity 365 -keystore /Users/xxx/Desktop/test.keystore
或者:
keytool -genkey -v -keystore test.keystore -alias test -keyalg RSA -validity 365 -storepass 123456
(2)一次性生成:
keytool -genkey -alias test -keypass test -keyalg RSA -keysize 1024 -validity 365 -keystore 指定路徑/test.keystore -storepass 123456 -dname "CN=(名字與姓氏), OU=(組織單位名稱), O=(組織名稱), L=(城市或區域名稱), ST=(州或省份名稱), C=(單位的兩字母國家代碼)"
(中英文即可)
keystore信息的查看:
keytool -list -v -keystore test.keystore -storepass 123456
參數說明:
- -genkey 【生成密鑰對】
- -alias 【別名】
- -keypass 【私鑰舊密碼】
- -keyalg 【關鍵算法】
- -keysize 【密鑰長度】
- -validity 【有效時長,以天為單位】
- -keystore 【密鑰存儲庫位置】
- -storepass 【密鑰庫密碼】
- -dname 【指定證書擁有者信息】
一般在公司會在項目中的 keystore 目錄下創建一個 key.properties 文件,來記錄 keystore 關鍵信息,里面的內容是:
key.store=keystore/test.keystore
key.store.password=123456
key.alias=test
key.alias.password= testmima
key.sigalg=RSA
Android 怎么簽名
通過使用 Java 自帶的 keytool 和 jarsigner 工具或 apksigner 工具(android 11)進行簽名。
使用 jarsigner 簽名
/Library/Java/JavaVirtualMachines/xxx.jdk/Contents/Home/bin
需要進入到 jarsigner 所在的位置,通過以下命令可以對名為 test 的 apk 簽名:
jarsigner -verbose -keystore test.keystore【keystore路徑】 test.apk 【apk 名稱】test【別名】
如何查找 jdk 位置
java -version 可以查看 java 版本
java -verbose 可以查看 jdk 路徑,和其他信息
java -verbose
簽名時遇到的問題
在android 11的設備上安裝時 可能會出現:
Failure [-124: Failed parse during installPackageLI: Targeting R+ (version 30 and above) requires the resources.arsc of installed APKs to be stored uncompressed and aligned on a 4-byte boundary] 的問題
以上問題的原因:
是關于zip 4字節對齊,請參考zipalign
解決方法:
使用 apksigner 對其簽名
假設需要被簽名的文件為:source.apk
- 先進入 /Users/xxx/Library/Android/sdk/build-tools/30.0.3 路徑中
- 先刪除了客戶的v1簽名,即刪除 META-INF目錄(META-INF目錄下存放的是簽名信息,可能報找不到META-INF/* ,不重要)
zip -d source.apk META-INF/*
- 獲取4KB對齊apk(source_4.apk 是對齊后的結果文件)
zipalign -v 4 source.apk source_4.apk
- 查看是否結果文件是否對齊 (成功后會報:Verification succesful)
zipalign -c -v 4 source_4.apk
- 然后通過 apksigner 簽名,不能在使用 jarsigner 簽名
apksigner sign --ks (簽名地址) --ks-key-alias (別名) --out (簽名后的apk地址) (待簽名apk地址)
- 密碼庫短語是:keystore 的 password (上文的 123456)
查看 apk 是否簽名
查看source_4.apk 是否簽名,是什么類型的簽名
apksigner verify -v source_4.apk
查看 Apk 的MD5值或 SHA1 以及MD5不顯示時的解決辦法
- 將以 .apk 結尾的 APK 文件更換為 .zip 文件
- 解壓 zip 文件找到 META-INF/xx.RSA 文件
- 命令查看 MD5 信息
keytool -printcert -file 【xx.RSA文件所在路徑】
有的時候 看不到 MD5 值,可以使用命令行:
jadx-gui 目標文件.apk
中的 APK signature 查看MD5 簽名、SHA-1 簽名、SHA-256 簽名信息
例如:
xx.RSA文件是簽名文件,它的命名如果不指定名稱則自動截取別名中前8個字符
一般上傳到市場平臺的時候,被提示解析失敗,沒有簽名文件,可能就是缺少了這個文件。
缺少 xx.RSA 文件的原因
缺少 xx.RSA 文件的原因,大概率是因為沒有選中 V1 這種簽名方式。
V1 vs V2
V2這種簽名方案是 Android 7.0引入的,它能提供更快的應用安裝時間和更多針對未授權 APK 文件更改的保護。具體請看 這里 。 而V1適用于所有android版本的機型,但在Android7.0及以上會缺少針對未授權 APK 文件更改的保護;所以只選V2,Android7.0以下的機型會報錯,同時選V1,V2,適用所有機型。
命令行打包默認 V1,V2 是都選中的,如果不放心可以在 build.gradle 里做設置
在 app 的 build.gradle 的 android 標簽下加入如下:
signingconfigs {
debug {
v1signingenabled true
v2signingenabled true
}
release {
v1signingenabled true
v2signingenabled true
}
}