Android : apk簽名的多種方法以及key的配置


  方法一:使用Android SDK中的簽名工具給apk簽名:

  (1)Android源碼的 build/target/product/security/ 目錄下有 media.pk8、media.x509.pem、platform.pk8、platform.x509.pem、shared.pk8、shared.x509.pem、testkey.pk8、testkey.x509.pem等簽名文件,不同的簽名文件對應不同的權限,Android默認的簽名文件為testkey.pk8、testkey.x509.pem。

    

    (2) Android SDK中的簽名工具為 signapk.jar,具體路徑:out/host/linux-x86/framework/signapk.jar,簽名指令如下:

       java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk

 8.0上驗證需要額外的一些參數:    (直接在源碼根目錄執行簽名,但是7.0以上采用 APK Signature Scheme v2,會導致安裝不了,但是增加參數 --disable-v2 無效知道原因的朋友還請告知一下!)

    java -Xmx2048m -Djava.library.path="out/host/linux-x86/lib64" \
    -jar out/host/linux-x86/framework/signapk.jar  --disable-v2 \
    -w build/target/product/security/platform.x509.pem \
    build/target/product/security/platform.pk8 \
    old.apk new.apk

 

  方法二:通過Android.mk配置編譯成簽名apk:

  (1)編寫Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := app   //要簽名的apk名稱
LOCAL_SRC_FILES := app.apk //apk文件
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := .apk
LOCAL_BUILT_MODULE_STEM := package.apk
LOCAL_CERTIFICATE := platform  //系統簽名
LOCAL_DEX_PREOPT := false
LOCAL_PRIVILEGED_MODULE := true
include $(BUILD_PREBUILT)

    (2) 將apk放入.mk同目錄(命名為app.apk),配置好sdk編譯環境后執行mm指令編譯,簽名apk生成在:out/target/product/xxxx/system/priv-app/app/app.apk 。

注:LOCAL_CERTIFICATE := platform         表示使用系統簽名
  LOCAL_DEX_PREOPT := false    不提前優化,無oat文件

  
方法三:Android studio配置key簽名:

(1)生成key:

------>生成本地key:

----------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------

 

------>生成系統平台key:

 下載 keytool-importkeypair 工具,使用sdk的security文件生成對應平台的key:

./keytool-importkeypair -k [jks文件名] -p [jks的密碼] -pk8 platform.pk8 -cert platform.x509.pem -alias [jks的別名]

如:
./keytool-importkeypair -k ./SignDemo.jks -p 123456 -pk8 platform.pk8 -cert platform.x509.pem -alias SignDemo

 

(2)使用key:

通過以上方法生成的SignDemo.jks更新到android studio原來設置的目錄,下一步即可生成簽名APK:

簽名apk生成路徑:\xxxx\app\release

實質是運行 Sdk\build-tools\27.0.3\lib\apksigner.jar 進行簽名:

  java -jar apksigner.jar sign        //執行簽名操作
    --ks 你的jks路徑            //jks簽名證書路徑
    --ks-key-alias 你的alias      //生成jks時指定的alias
    --ks-pass pass:你的密碼    //KeyStore密碼
    --key-pass pass:你的密碼    //簽署者的密碼,即生成jks時指定alias對應的密碼
    --out output.apk         //輸出路徑
    input.apk          //被簽名的apk
補充:

 V1簽名(jarsigner方式):

//jarsigner -verbose -keystore (簽名地址) -signedjar (簽名后的apk地址) (待簽名apk地址) (別名) 
jarsigner -verbose -keystore D:\itlao5.keystore -signedjar D:\itlao5_signed.apk D:\itlao5.apk itlao5

V2簽名(apksigner方式):

// apksigner sign --ks (簽名地址) --ks-key-alias (別名) --out (簽名后的apk地址) (待簽名apk地址)
apksigner sign --ks D:\itlao5.keystore --ks-key-alias itlao5 --out D:\itlao5_signed.apk D:\itlao5.apk

驗證簽名是否成:

apksigner verify -v --print-certs (apk地址)

 

每次生成簽名apk都要選擇 Build->Generate Signed APK 配置一下key,豈不是很麻煩?當然有簡化方法,生成.jks后可以在項目的app目錄下的build.gradle中進行配置,步驟如下:

  ① File -> Project structure -> Signing:

    

 

     ② File -> Project structure -> Flavors:

 

   ③ File -> Project structure -> Build Types:

 

 

通過以上配置步驟后,可在build.gradle中可以看到增加了如下配置信息(粗體),當然也可以手動直接在build.gradle中輸入配置信息:

android {
 signingConfigs { release { keyAlias 'SignDemo' keyPassword '123456' storeFile file('E:/project/androidStudio/signAPK/SignDemo.jks') storePassword '1234546' } }
......
    buildTypes {
        release { //生成release apk
            zipAlignEnabled true //4字節對齊,減少運行內存消耗 
            minifyEnabled true  //false = 關閉混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release
        }
        debug { //生成debug apk
            zipAlignEnabled true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

}

   然后通過Build Variants選擇對應的項目版本,直接編譯生成簽名apk,省去之前每次選擇key麻煩。

 

  然而對於一些開源項目,直接在build.gradle中顯式配置key,那密碼等信息就泄露了,所以可以把相關信息定義在local.properties中,因為local.properties存儲的是本地環境資源的一些相關信息,默認不加入代碼版本管理,然后build.gradle中引用其變量即可:

  ①在local.properties中添加信息:

## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Mon Nov 26 16:21:41 CST 2018
ndk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk\\ndk-bundle
sdk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk

keystore.path=E\:/project/androidStudio/signAPK/SignDemo.jks keystore.password=123456 keystore.alias=SignDemo keystore.alias_password=123456

  ②在build.gradle中引用其定義的值:

    signingConfigs {
        release {
            //加載資源
            Properties properties = new Properties()
            InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream()
            properties.load(inputStream)

            //讀取文件
            def sdkDir = properties.getProperty('keystore.path')
            storeFile file(sdkDir)

            //讀取字段
            def key_keyAlias = properties.getProperty('keystore.alias')
            def key_keyPassword = properties.getProperty('keystore.password')
            def key_storePassword = properties.getProperty('keystore.alias_password')

            keyAlias key_keyAlias
            keyPassword key_keyPassword
            storePassword key_storePassword
        }
    }

......

    buildTypes {
        release { //生成release apk
            zipAlignEnabled true //4字節對齊,減少運行內存消耗 
            minifyEnabled true  //false = 關閉混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release
        }
    }

通過以上方法就可以在build.gradle中隱式配置key,而Project Structure中就不用再配置key相關信息了:

 

 

 

關於system app的提示:

  平台簽名的apk,如果 AndroidManifest.xml 中指定是 android:sharedUserId="android.uid.system",即為system app:

 

 

-end-

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM