如何使用 gradle 使用平台密钥签署 android 应用程序?
How to sign android app with platform keys using gradle?
我看到了几个类似的问题,例如:
- Android: After building platform source, how to sign arbitrary APK with platform key?
- How to create a release signed apk file using Gradle?
- APK signing error : Failed to read key from keystore
但我觉得我的问题不一样。
首先我使用:
android:sharedUserId="android.uid.system"
所以我需要使用平台密钥签署我的应用程序。我可以这样:
cd $ANDROID_ROOT/out/host/linux-x86/framework
java -Djava.library.path=$ANDROID_ROOT/out/host/linux-x86/lib64 -jar signapk.jar $ANDROID_ROOT/build/target/product/security/platform.x509.pem $ANDROID_ROOT/build/target/product/security/platform.pk8 $APP_DIR/app/build/outputs/apk/debug/app-debug.apk $APP_DIR/MyApp-signed.apk
但是我想从 gradle 进行签名,所以我以 this 的方式生成了 jks 文件:
./keytool-importkeypair -k my_keystore.jks -p my_password -pk8 $ANDROID_ROOT/build/target/product/security/platform.pk8 -cert $ANDROID_ROOT/build/target/product/security/platform.x509.pem -alias platform
并且我修改了 app/build.gradle 以具有:
signingConfigs {
release {
storeFile file("my_keystore.jks")
storePassword "my_password"
keyAlias "platform"
keyPassword "my_password"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
我检查过 my_keystore.jks 有平台别名:
keytool -list -v -keystore my_keystore.jks | grep Alias
Alias name: platform
但是当我尝试这样做时:
./gradlew assembleRelease
或:
./gradlew signingReport
我得到:
Failed to read key platform from store "(...)/my_keystore.jks": Invalid keystore format
更新:
我已经尝试遵循 dr_g 提示,并且我能够使用 Android Studio(构建 -> 生成已签名的 APK)对应用程序进行签名,所以我猜密钥库是好的,但是在使用 assembleRelease 时我仍然遇到同样的错误。
我还尝试按照 deadfish 的建议生成我自己的密钥库,实际上 Android Studio 生成的密钥库适用于 gradle 并且 assembleRelease 有效,但它不是平台钥匙,所以不幸的是我不能使用它。
问题已解决:
事实证明,我的问题确实与我提到的问题不同。它与用于生成密钥的 keytool(不是 gradle)有关,这是因为虽然我的默认 java 是 8,但我的默认 keytool 来自 java 10 ... 当我切换时从 java 8 到 keytool 一切开始正常工作。
使用 .keystore 文件而不是 .jks
当您生成应用程序时,Android studio 会注意到您创建了一个 keyStore,试试这个密钥。
请尝试使用 .keystore 变体。可能有修复 java 密钥库 (.jks) 格式的方法,但可能需要更多时间。
1) 从单独的密钥文件生成 .keystore 文件
$ openssl pkcs8 -inform DER -nocrypt -in \
$ANDROID_ROOT/build/target/product/security/platform.pk8 -out platform.key
$ openssl pkcs12 -export -in \
$ANDROID_ROOT/build/target/product/security/platform.x509.pem -inkey \
platform.key -name platform -out platform.pem -password pass:password
$ keytool -importkeystore -destkeystore platform.keystore -deststorepass \
password -srckeystore platform.pem -srcstoretype PKCS12 -srcstorepass
password
2) 测试您的新密钥库:
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore \
platform.keystore -storepass password your-app.apk platform
3) 在您的 gradle 构建中部署密钥库:
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
release {
storeFile file('platform.keystore')
storePassword 'password'
keyAlias 'platform'
keyPassword 'password'
}
}
上面的 build.gradle 还显示了使用 android 调试密钥库作为调试构建标准的示例。
在与 deadfish 交谈并遵循他的建议(感谢您的帮助!)后,我在 app/build.gradle(在 android 中提出了以下解决方法{}):
applicationVariants.all { variant ->
variant.assemble.doLast {
exec {
commandLine 'sh', '../mySigningScript.sh'
}
}
}
每次 assembleDebug 或 assembleRelease 完成时,这将 运行 我的脚本。我不会接受我的回答,因为它没有回答我的问题,它迫使我从 gradle 中删除 signingConfigs,但至少这是一种解决方法,如果没有提出更好的解决方案,可能会被使用。
对于 从 x509.pem 和 pk8 文件创建密钥库,您可以使用此脚本 platform_import_keystore,它类似于 keytool-importkeypair,但考虑到如果您没有现有的密钥库,keytool-importkeypair 将不起作用,platform_import_keystore 可以。
希望对您有所帮助。
编辑:
脚本 platform_import_keystore
使用默认的 keytool
命令。您必须确保脚本中使用的命令 keytool
来自 java 8
。这会影响 keytool
.
获得的密钥库格式
我看到了几个类似的问题,例如:
- Android: After building platform source, how to sign arbitrary APK with platform key?
- How to create a release signed apk file using Gradle?
- APK signing error : Failed to read key from keystore
但我觉得我的问题不一样。
首先我使用:
android:sharedUserId="android.uid.system"
所以我需要使用平台密钥签署我的应用程序。我可以这样:
cd $ANDROID_ROOT/out/host/linux-x86/framework
java -Djava.library.path=$ANDROID_ROOT/out/host/linux-x86/lib64 -jar signapk.jar $ANDROID_ROOT/build/target/product/security/platform.x509.pem $ANDROID_ROOT/build/target/product/security/platform.pk8 $APP_DIR/app/build/outputs/apk/debug/app-debug.apk $APP_DIR/MyApp-signed.apk
但是我想从 gradle 进行签名,所以我以 this 的方式生成了 jks 文件:
./keytool-importkeypair -k my_keystore.jks -p my_password -pk8 $ANDROID_ROOT/build/target/product/security/platform.pk8 -cert $ANDROID_ROOT/build/target/product/security/platform.x509.pem -alias platform
并且我修改了 app/build.gradle 以具有:
signingConfigs {
release {
storeFile file("my_keystore.jks")
storePassword "my_password"
keyAlias "platform"
keyPassword "my_password"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
我检查过 my_keystore.jks 有平台别名:
keytool -list -v -keystore my_keystore.jks | grep Alias
Alias name: platform
但是当我尝试这样做时:
./gradlew assembleRelease
或:
./gradlew signingReport
我得到:
Failed to read key platform from store "(...)/my_keystore.jks": Invalid keystore format
更新: 我已经尝试遵循 dr_g 提示,并且我能够使用 Android Studio(构建 -> 生成已签名的 APK)对应用程序进行签名,所以我猜密钥库是好的,但是在使用 assembleRelease 时我仍然遇到同样的错误。 我还尝试按照 deadfish 的建议生成我自己的密钥库,实际上 Android Studio 生成的密钥库适用于 gradle 并且 assembleRelease 有效,但它不是平台钥匙,所以不幸的是我不能使用它。
问题已解决: 事实证明,我的问题确实与我提到的问题不同。它与用于生成密钥的 keytool(不是 gradle)有关,这是因为虽然我的默认 java 是 8,但我的默认 keytool 来自 java 10 ... 当我切换时从 java 8 到 keytool 一切开始正常工作。
使用 .keystore 文件而不是 .jks 当您生成应用程序时,Android studio 会注意到您创建了一个 keyStore,试试这个密钥。
请尝试使用 .keystore 变体。可能有修复 java 密钥库 (.jks) 格式的方法,但可能需要更多时间。
1) 从单独的密钥文件生成 .keystore 文件
$ openssl pkcs8 -inform DER -nocrypt -in \
$ANDROID_ROOT/build/target/product/security/platform.pk8 -out platform.key
$ openssl pkcs12 -export -in \
$ANDROID_ROOT/build/target/product/security/platform.x509.pem -inkey \
platform.key -name platform -out platform.pem -password pass:password
$ keytool -importkeystore -destkeystore platform.keystore -deststorepass \
password -srckeystore platform.pem -srcstoretype PKCS12 -srcstorepass
password
2) 测试您的新密钥库:
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore \
platform.keystore -storepass password your-app.apk platform
3) 在您的 gradle 构建中部署密钥库:
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
release {
storeFile file('platform.keystore')
storePassword 'password'
keyAlias 'platform'
keyPassword 'password'
}
}
上面的 build.gradle 还显示了使用 android 调试密钥库作为调试构建标准的示例。
在与 deadfish 交谈并遵循他的建议(感谢您的帮助!)后,我在 app/build.gradle(在 android 中提出了以下解决方法{}):
applicationVariants.all { variant ->
variant.assemble.doLast {
exec {
commandLine 'sh', '../mySigningScript.sh'
}
}
}
每次 assembleDebug 或 assembleRelease 完成时,这将 运行 我的脚本。我不会接受我的回答,因为它没有回答我的问题,它迫使我从 gradle 中删除 signingConfigs,但至少这是一种解决方法,如果没有提出更好的解决方案,可能会被使用。
对于 从 x509.pem 和 pk8 文件创建密钥库,您可以使用此脚本 platform_import_keystore,它类似于 keytool-importkeypair,但考虑到如果您没有现有的密钥库,keytool-importkeypair 将不起作用,platform_import_keystore 可以。
希望对您有所帮助。
编辑:
脚本 platform_import_keystore
使用默认的 keytool
命令。您必须确保脚本中使用的命令 keytool
来自 java 8
。这会影响 keytool
.