Android 的簽名有兩種方式,一種使用jdk 提供的jarsigner工具簽名keystore 文件,另一種是Android 自己提供的signapk.jar 通過.pk8(密鑰) 和.x509.pem(證書)兩個簽名文件完成簽名。 之前對一個包簽名都是直接使用signapk來的,因為不需要輸入... ...
原文鏈接:http://blog.votzone.com/2018/05/05/android_signature.html Android 的簽名有兩種方式,一種使用jdk 提供的jarsigner工具簽名keystore 文件,另一種是Android 自己提供的signapk.jar 通過.pk8(密鑰) 和.x509.pem(證書)兩個簽名文件完成簽名。 之前對一個包簽名都是直接使用signapk來的,因為不需要輸入密碼即可直接簽名,簡單直接,今天上傳百度時遇到問題了,下載下來簽名說明文檔後說需要使用jarsigner 來簽名,於是研究了下兩個簽名之間相互轉換的問題。 並且為了降低以後再次遇到這類問題時查找資料的成本,寫了個簡易的bat腳本半自動化操作。 工具: openssl 安裝完成之後, 將bin目錄加入環境變數即可使用openssl keytool jdk/bin目錄下的工具 signapk.jar 用於Android簽名的工具(源碼在aosp的源代碼下) jarsigner jdk 中的工具,用於給jar簽名(也可以給任意一個zip包簽名) 一、兩種不同簽名方案的簽名過程 1、jarsigner 是jdk 提供的工具,安裝jdk之後就可以使用了,使用jarsigner簽名的命令如下:
jarsigner -verbose -storepass 12345678 -keystore testkey.jks -signedjar signed_out.apk 111.zip testkey
其中 -verbose 表示輸出詳細信息 -storepass 表示簽名庫的密碼 -keystore 表示簽名文件路徑 -signedjar 表示簽名後輸出文件路徑 最後跟需要簽名的 文件路徑 和 keystore 的別名 詳細參數可以通過 jarsigner -help 查看,中文的還是很清楚。 2、signapk 是android 提供的單獨為apk簽名的工具,使用方法:
java -jar signapk.jar testkey.x509.pem testkey.pk8 111.zip signed_out.apk
可知,jarsigner 簽名需要提供一個簽名文件jks 和簽名庫密碼,並且如果簽名庫密碼跟密鑰密碼不同還需另外提供密鑰密碼;(下文我們稱jks 簽名或jks簽名庫) signapk 簽名只需提供一個pk8文件和一個x509.pem文件即可。(下文將這兩個文件簡稱為pk8簽名) 二、將pk8簽名轉換為jks 簽名庫 接下來我們解決百度渠道的簽名問題,第一步就需要將我們的pk8簽名 轉換為 jks簽名。 通過網上搜索,我們瞭解到java簽名庫文件通常的尾碼有.keystore 和.jks,因此我們可以認為之前eclipse時代的.keystore簽名與Android Studio 時代的.jks 簽名是相同格式的。 現在我們有pk8簽名,可以使用openssl 和keytool 兩個工具來將其合併到jks簽名庫 下麵以實例介紹將testkey.pk8/testkey.x509.pem 簽名文件 合併到testkey.jks 簽名庫,並設置其密碼12345678和別名testkey a)
openssl pkcs8 -inform DER -nocrypt -in testkey.pk8 -out testkey.pem
使用 open ssl 將pk8 解密為 pem 文件, 此時生成一個testkey.pem 文件
b)openssl pkcs12 -export -in testkey.x509.pem -inkey testkey.pem -out platform.p12 -password pass:12345678 -name testkey
將兩個pem 文件導入platform.p12文件中,並設置 別名 testkey 和keypass 密碼:12345678 (別名和密碼可自定義)
會新生成 platform.p12 c)keytool -importkeystore -deststorepass 12345678 -destkeystore testkey.jks -srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass 12345678
使用keytool 將之前生成的platform.p12導入 testkey.jks 簽名中,並設置storepass密碼(12345678)
需要正確提供keypass 密碼 此時即生成了需要的testkey.jks 簽名文件 d)keytool -list -v -keystore testkey.jks
查看生成的 簽名信息
註意: storepass 和 keypass 可以不同 兩個密碼相同情況下 使用jarsigner 簽名時只需提供storepass即可 否則需要提供兩個密碼 keytool -list 查看時只需提供storepass即可 有了jks簽名庫,我們為空包簽名jarsigner -verbose -storepass 12345678 -keystore testkey.jks -signedjar jks_out.apk 111.zip testkey
命令通過提供-stroepass(密碼) 和別名(testkey) 將輸入文件111.zip 簽名為jks_out.apk 接下來我們提供一個將pk8簽名生成jks的簡易bat腳本, 腳本中需要配置 openssl keytool 路徑,並且手動設置需要簽名的文件名。 腳本見文章末尾github代碼庫中 cvt2jks.bat 工具運行目錄如下 參考: https://blog.csdn.net/S_targaze_R/article/details/50739802 三、從將jks簽名庫中抽取pk8簽名 openssl能夠將signapk 用的簽名合併到 jarsigner簽名, 同樣也可以分離出來,具體操作步驟: a)
keytool -importkeystore -srckeystore testkey.jks -destkeystore testkey.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass 12345678 -deststorepass 12345678 -noprompt
首先將testkey.jks 轉化為 .p12文件, 在執行過程中需要輸入srcstore密碼和 deststroe 密碼, 這裡在命令行中 通過-srcstorepass 和-deststorepass指定
b)openssl pkcs12 -in testkey.p12 -nodes -out testkey_all.rsa.pem -password pass:12345678
使用openssl 的pkcs12 指令將p12文件中的證書導出,
-password pass:12345678 為了省略之後的輸入密碼步驟 通過網上的教程可知,如上代碼同時導出了密鑰 和 證書, 需要手動的將證書複製出來生成 .x509.pem簽名 查看openssl幫助文檔, 我們知道可以只導出證書或者密鑰,於是我們可以通過 -nokeys 參數只導出證書openssl pkcs12 -in testkey.p12 -nodes -nokeys -out testkey.x509.pem -password pass:12345678
通過-cacerts 參數之導出密鑰
openssl pkcs12 -in testkey.p12 -nodes -cacerts -out testkey.rsa.pem -password pass:12345678
c) 根據b)中生成的密鑰文件生成pk8, 可以使用testkey_all.rsa.pem 也可是使用testkey.rsa.pem
openssl pkcs8 -topk8 -outform DER -in testkey.rsa.pem -inform PEM -out testkey.pk8 -nocrypt
如上testkey.pk8 和 testkey.x509.pem即為所需簽名 一個簡易bat 腳本 見文章末尾github代碼庫中 jks2pk8.bat 文件 參考 https://blog.csdn.net/sendwave/article/details/73699352 四、探究jks 簽名的生成 我們知道可以使用Android Studio 來生成jks, 是不是有命令行工具呢 keytool 就可以實現 這個操作 核心命令 keytool -genkey -v -keystore app.jks -alias app -keyalg RSA -validity 999999 如上,指定了 要生成的簽名文件名稱 , 別名 和有效期(日) 運行過程中需要輸入兩個密碼 一個是密碼口令(keypass),一個是密鑰庫口令(storepass) 可以通過-keypass 和 -storepass 指定 簡易 bat腳本 見文章末尾github代碼庫中 genkey.bat 文件 參考 https://blog.csdn.net/darkengine/article/details/42773745 五、簽名案例分析 創建一個jks 簽名app.jks, 將jks 簽名拆分為signapk需要的pk8簽名, 然後再將pk8 簽名合併回jks 分別用如上三個簽名對同意文件進行簽名操作, 對比如下: 證書都相同! PS:附使用 signapk.jar 和jarsigner 工具簽名的命令行操作 signapk.jar 簽名示例 java -jar signapk.jar testkey.x509.pem testkey.pk8 111.zip jifei_out.apk jarsigner 工具簽名示例 jarsigner -verbose -storepass 12345678 -keystore testkey.jks -signedjar jks_out.apk 111.zip testkey 最後的testkey 為別名 腳本: https://github.com/votzone/DroidCode/tree/master/Signature