1. 程式人生 > >Apk去掉簽名以及重新簽名的方法

Apk去掉簽名以及重新簽名的方法

Android開發中很重要的一部就是用自己的金鑰給Apk檔案簽名,不經過簽名的Apk檔案一般是無法安裝的,就算裝了最後也是失敗。

網上流傳的“勾選允許安裝未知來源的應用”其實跟籤不簽名沒啥關係,說白了就是允許安裝不從電子市場上下載的應用而已。

近幾日需要修改一個Apk中JNI呼叫的.so檔案,苦於沒有apk原始碼,只好研究了一下簽名相關的問題。當然有很多第三方工具可以做到,但其實JDK中已經提供了強大的簽名工具jarsigner。

    1. 去除簽名

      其實很簡單,用WinRAR開啟apk,找到META-INF資料夾,刪除MANIFEST.MF之外的所有其他檔案即可。

    2. 簽名

      執行jarsigner,如果沒有設定PATH環境變數,那可以從JDK安裝路徑下的bin目錄中找到,比如我本機的就是C:\Program Files\Java\jdk1.8.0_31\bin\jarsigner.exe

      jarsigner用法如下:

      用法: jarsigner [選項] jar-file 別名
             jarsigner -verify [選項] jar-file [別名...]
      
      [-keystore <url>]           金鑰庫位置
      
      [-storepass <口令>]         用於金鑰庫完整性的口令
      
      [-storetype <型別>]         金鑰庫型別
      
      [-keypass <口令>]           私有金鑰的口令 (如果不同)
      
      [-certchain <檔案>]         替代證書鏈檔案的名稱
      
      [-sigfile <檔案>]           .SF/.DSA 檔案的名稱
      
      [-signedjar <檔案>]         已簽名的 JAR 檔案的名稱
      
      [-digestalg <演算法>]        摘要演算法的名稱
      
      [-sigalg <演算法>]           簽名演算法的名稱
      
      [-verify]                   驗證已簽名的 JAR 檔案
      
      [-verbose[:suboptions]]     簽名/驗證時輸出詳細資訊。
                                  子選項可以是 all, grouped 或 summary
      
      [-certs]                    輸出詳細資訊和驗證時顯示證書
      
      [-tsa <url>]                時間戳頒發機構的位置
      
      [-tsacert <別名>]           時間戳頒發機構的公共金鑰證書
      
      [-tsapolicyid <oid>]        時間戳頒發機構的 TSAPolicyID
      
      [-altsigner <類>]           替代的簽名機制的類名
      
      [-altsignerpath <路徑列表>] 替代的簽名機制的位置
      
      [-internalsf]               在簽名塊內包含 .SF 檔案
      
      [-sectionsonly]             不計算整個清單的雜湊
      
      [-protected]                金鑰庫具有受保護驗證路徑
      
      [-providerName <名稱>]      提供方名稱
      
      [-providerClass <類>        加密服務提供方的名稱
        [-providerArg <引數>]]... 主類檔案和構造器引數
      
      [-strict]                   將警告視為錯誤

      比較常用的引數就是指定keystore的位置和簽名後的檔案,舉例如下:

      jarsigner -keystore C:\myKey.key -signedjar apk-signed.apk apk-unsigned.apk myKey

      待簽名的檔案是apk-unsigned.apk,簽名後的apk是apk-signed.apk。我們也可以不指定-signedjar引數,則在待簽名的apk上直接簽名。最後一個myKey是我的keystore的別名。

      簽名完成後再用WinRAR開啟,會發現META-INF目錄下多了MYKEY.RSA和MYKEY.SF兩個檔案,他們分別是:
      MANIFEST.MF中儲存了所有其他檔案的SHA-1並base64編碼後的值。
      MYKEY.SF中也有其他檔案的SHA-1並base64編碼的值,而且還多一個MANIFEST.MF檔案的SHA-1並base64編碼後的值
      MYKEY.RSA包含了公鑰資訊和釋出機構資訊
      後兩個檔案的名稱和我的key別名轉換為大寫後一致。

這裡要用到Android SDK中的一個工具jarsigner,只要配置了SDK環境變數就可以直接使用

 

方法一(推薦):

複製命令到記事本儲存為apk-sign.bat後執行

set/p keystore_path=請輸入.keystore的檔案路徑:
set/p alias_path=請輸入keystore的alias:
set/p unsign_path=請輸入待簽名的apk檔案路徑:
set/p sign_path=請輸入簽名後生成的apk檔案路徑:
 
jarsigner -verbose -keystore %keystore_path% -signedjar %sign_path% %unsign_path% %alias_path%
 
pause

 執行後根據提示填上對應的資訊,最後輸入keystore的密碼,提示jar 已簽名,就大功告成了。

 

方法二:

除了方法一也可以在命令列裡直接用一行命令解決,但需要4個引數:

①keystore檔案路徑

②簽名後生成的apk路徑

③待簽名的apk路徑

④alias別名

 

jarsigner -verbose -keystore keystore檔案路徑 -signedjar 簽名後生成的apk路徑 待簽名的apk路徑 別名

1.例如,我已有的.keystore檔案在D:\app\keystore的目錄下,名為demo.keystore

2.待簽名的apk在D:\app\apk的目錄下,檔名是unsign.apk

3.簽名後會產生一個新的apk,然後我要讓新apk也生成在D:\app\apk目錄下

4.keystore裡面可能會存在多個別名,所以要註明一下別名,這裡我的別名就是demo

把這4個引數合成完整的命令就是:

jarsigner -verbose -keystore D:\app\keystore\demo.keystore -signedjar D:\app\apk\unsign.apkD:\app\apk\sign.apk demo