文章目錄
keytool、jarsigner 均是jdk提供的工具,JDK下載
涉及的文件可以參考示例 AndroidSignKeyConvert
Android 簽名機制 v1、v2、v3 參閱 https://www.jianshu.com/p/9ca1d6f3f083
1. 生成APK簽名文件
1.1 使用keytool命令生成.jks
keytool -genkeypair -alias business -keypass 123456 -keystore ./genkey.jks -storepass 123123 -validity 120000
將會生成簽名文件./genkey.jks
,有效期1200
個月,別名business
,密鑰庫的密碼123123
,business
的密碼123456
可將./genkey.jks
直接換./genkey.keystore
生成.keystore簽名文件
1.2. 使用IDE生成,IntellJ的生成如下
菜單 Build–>Generate Signed APK–>Create new
2. 查看簽名文件的簽名信息
keytool -list -v -keystore genkey.jks
需要用到之前生成簽名文件的密鑰庫的密碼123123
3. 對apk簽名的幾種方式
3.1 用指定的keystore 簽名apk
jarsigner -keystore ./genkey.jks -signedjar ./signed.apk ./unsigned.apk business
輸入密鑰庫的密碼短語: //123123
輸入business的密鑰口令: //123456
jar 已簽名。
將unsigned.apk
用./genkey.jks
的business
密匙簽名爲signed.apk
需要用到之前生成簽名文件的兩個密碼
3.2 使用platform.x509.pem和platform.pk8對apk簽名
此種情況多見Android系統開發中,對系統應用簽名
有如下新舊兩種命令
java -jar apksigner.jar sign --key genkey.pk8 --cert genkey.x509.pem --in unsigned.apk --out signed.apk
- 這個是新的簽名方式,參考apksigner
- apksigner.jar 來自…\sdk\build-tools\29.0.0\lib\
java -jar apksigner.jar sign --help
命令的幫助說明
java -jar signapk.jar platform.x509.pem platform.pk8 unsigned.apk signed.apk
- signapk.jar 可以編譯Android源碼(
mmm build/tools/signapk/
) 得到,源碼中位置prebuilts/sdk/tools/lib/signapk.jar
也可能有 - platform.x509.pem和platform.pk8在源碼目錄
build/target/product/security/
中
3.3 使用集成IDE對APK簽名
多數IDE(IntellJ/AS)是在菜單build–>Generate Signed APK中
Android Studio 可以自動簽名,需要在build.gradle中添加如下配置
signingConfigs {
config {
storeFile file('../genkey.jks')
storePassword '123123'
keyAlias "business"
keyPassword '123456'
}
}
buildTypes {
release {
minifyEnabled false
signingConfig signingConfigs.config
}
}
本文地址 http://blog.csdn.net/CSqingchen/article/details/78228933
4. 用keytool查看應用(APK)的簽名
- 將簽名後的
signed.apk
解壓縮到目錄signed,得到簽名文件.\signed\META-INF\BUSINESS.DSA
, - 使用keytool可以查看
keytool -printcert -file ./BUSINESS.DSA
本文地址http://blog.csdn.net/CSqingchen/article/details/78228933
5. 簽名文件轉換之 .jks轉 .keystone
5.1 .jks 轉 .p12
keytool -importkeystore -srckeystore ./genkey.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore genkey.p12
輸入目標密鑰庫口令://123456
再次輸入新口令://123456
輸入源密鑰庫口令://123123
輸入 <business> 的密鑰口令 //123456
已成功導入別名 business 的條目。
已完成導入命令: 1 個條目成功導入, 0 個條目失敗或取消
5.2 .p12 轉 .keystore
keytool -v -importkeystore -srckeystore ./genkey.p12 -srcstoretype PKCS12 -destkeystore ./genkey.keystore -deststoretype JKS
輸入目標密鑰庫口令://123123
再次輸入新口令://123123
輸入源密鑰庫口令://123456
已成功導入別名 business 的條目。
已完成導入命令: 1 個條目成功導入, 0 個條目失敗或取消
[正在存儲./genkey.keystore]
可以用以下命令效驗.jks和.keystore簽名數據,密碼都是123123
keytool -list -v -keystore genkey.jks
keytool -list -v -keystore genkey.keystore
6. 簽名文件轉換之 .keystore轉.x509.pem和.pk8
需要用到openssl,windows可以在Git安裝目錄找到,如’C:\Program Files\Git\mingw64\bin’,linux中沒有的自信安裝
- 將PKCS12格式的key dump爲可直接閱讀的文本
openssl pkcs12 -in genkey.p12 -nodes -out genkey.rsa.pem
Enter Import Password: //參考如上5.1 p12的密碼123456
- 提取genkey.rsa.pem爲genkey_private.rsa.pem和genkey.x509.pem
用文本編輯器打開 genkey.rsa.pem,將從
-----BEGIN PRIVATE KEY-----
到
-----END PRIVATE KEY-----
這一段(包含這兩個tag)的文本複製出來,新建爲文件 genkey_private.rsa.pem
將從
-----BEGIN CERTIFICATE-----
到
-----END CERTIFICATE-----
這一段(包含這兩個tag)的文本複製出來,新建爲文件 genkey.x509.pem (簽名時用到的公鑰)
- 生成pk8格式的私鑰
openssl pkcs8 -topk8 -outform DER -in genkey_private.rsa.pem -inform PEM -out genkey.pk8 -nocrypt
- 至此步驟3.2中的.x509.pem和.pk8 已經生成,可以用如下命令簽名
java -jar apksigner.jar sign --key genkey.pk8 --cert genkey.x509.pem --in unsigned.apk --out signed.apk
7. 應用中獲取簽名信息
參考自https://blog.csdn.net/anydrew/article/details/51227517
普通APP只能獲取自己的簽名信息,無法獲取其它應用的
核心代碼整理如下,參見測試代碼 MainActivity.java
public String getAppSign() {
String result = null;
PackageManager packageManager = getPackageManager();
try {
PackageInfo packageInfo = packageManager.getPackageInfo(
getPackageName(), PackageManager.GET_SIGNATURES);
if (packageInfo == null) {
return null;
}
Signature[] signatures = packageInfo.signatures;
if (signatures == null || signatures.length < 1) {
return null;
}
Signature signature = signatures[0];
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
//messageDigest = MessageDigest.getInstance("SHA-1");
//取MD5的值並轉String
byte[] md5Bytes = messageDigest.digest(signature.toByteArray());
//對生成的16字節數組進行補零操作
StringBuilder md5 = new StringBuilder(md5Bytes.length * 2);
for (byte b : md5Bytes) {
if ((b & 0xFF) < 0x10) {
md5.append("0");
}
md5.append(Integer.toHexString(b & 0xFF));
}
result = md5.toString();
} catch (Exception e) {
e.printStackTrace();
}
Log.d("getAppSign", "getAppSign result:" + result);
return result;
}
原創文章,轉載請註明出處、原文鏈接![email protected] 我的主頁https://chenjim.com
參考文章
Docs About keytool By Oracle
Android 根據包名,獲取應用程序的簽名
java keytool證書工具使用小結
Android將jks簽名文件轉爲keystore