Android 簽名基礎知識

文章大綱:

  • 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
image

(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

image

參數說明:

  • -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

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 簽名信息

例如:


看不到 MD5 值
通過 jadx-gui 查看 MD5

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
        }
    }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容