如何使用 gradle 使用平台密钥签署 android 应用程序?

How to sign android app with platform keys using gradle?

我看到了几个类似的问题,例如:

但我觉得我的问题不一样。

首先我使用:

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.

获得的密钥库格式