cordova-android icon indicating copy to clipboard operation
cordova-android copied to clipboard

Password from keystore password prompt is not used, placeholder "__unset" used as actual keystore password

Open ttencate opened this issue 5 years ago • 5 comments

Bug Report

Problem

What is expected to happen?

If we don't specify "storePassword" or "password" in build.json, then cordova build android --release will prompt for the password. That password should be used to access the keystore.

What does actually happen?

We get an error, even if the password was typed correctly:

> com.android.ide.common.signing.KeytoolException: Failed to read key my_key from store "my.keystore": Keystore was tampered with, or password was incorrect

If I change both the store and the key password to __unset (which is used in app/build.gradle as a temporary placeholder), then the signing step completes successfully, regardless of which password I entered in the prompt. So it seems that the password from the prompt does not successfully replace this placeholder.

Information

Command or Code

$ cordova create my_app
$ cd my_app
$ cordova platform add android
$ echo '{"android": {"release": {"keystore": "my.keystore", "alias": "my_key"}}}' > build.json
$ keytool -genkey -keystore my.keystore -alias my_key -v -keyalg RSA -keysize 2048 -validity 10000 -keypass testtest -storepass testtest
# Press Enter until "[no]" appears, then type "[yes]"
$ cordova build android --release
# Enter "testtest" at both password prompts
...
Execution failed for task ':app:packageRelease'.
> com.android.ide.common.signing.KeytoolException: Failed to read key my_key from store "/tmp/repro/my_app/my.keystore": Keystore was tampered with, or password was incorrect

But if the passwords happen to be __unset, it's better:

$ rm my.keystore 
$ keytool -genkey -keystore my.keystore -alias my_key -v -keyalg RSA -keysize 2048 -validity 10000 -keypass __unset -storepass __unset
# Press Enter until "[no]" appears, then type "[yes]"
$ cordova build android --release
...
BUILD SUCCESSFUL in 7s
43 actionable tasks: 2 executed, 41 up-to-date
Built the following apk(s): 
	/.../my_app/platforms/android/app/build/outputs/apk/release/app-release.apk

Environment, Platform, Device

Arch Linux on x86_64

Version information

  • Cordova CLI 9.0.0
  • Cordova lib 9.0.1
  • Cordova Android 8.0.0
  • Android SDK build tools 29.0.0

Checklist

  • [x] I searched for existing GitHub issues
  • [x] I updated all Cordova tooling to most recent version
  • [x] I included all the necessary information above

ttencate avatar Jul 05 '19 13:07 ttencate

I seem to have the same problem with my own app:

  • Cordova CLI 8.1.2
  • Cordova lib 8.1.1
  • Cordova Android 8.0.0
  • Android SDK build tools 29.0.0

Cannot build a release version, passwords entered seem to be ignored, getting error Keystore was tampered with, or password was incorrect

When creating a new app (following the code above) using these software versions I get the same error. When I remove platform android 8.0.0 and add platform android version 7.1.1 building succeeds.

robvandijk avatar Jul 23 '19 15:07 robvandijk

@robvandijk Can you confirm that using __unset as input works for you as well?

janpio avatar Jul 23 '19 15:07 janpio

That works for me as well. But this is likely due to the contents of the file signing-config.json at location platforms/android/app/intermediates/signing_config/release/out which always has contents

"mStorePassword":"__unset","mKeyPassword":"__unset"

I expect that the passwords provided by the user should end up in there, but they don't. Since these values always contain '__unset' this explains the behaviour you see.

robvandijk avatar Jul 23 '19 17:07 robvandijk

Yes, but we don't understand yet why that is happening unfortunately. We'll have to look deeper into that.

janpio avatar Jul 23 '19 17:07 janpio

I took a quick look at the Gradle source but I'm afraid I'm out of my depth here... As a workaround, just to be able to build a release version I made the following changes locally to platforms/android/app/build.gradle:

Add the following definition at the top of the file:

ext {
    inputStorePassword = '__unset'
    inputKeyPassword = '__unset'
}

Add the following method (key password and store password are assumed to be the same here):

def promptForReleaseKeyPasswordHack() {
    if ('__unset'.equals(inputStorePassword)) {
        inputStorePassword = privateHelpers.promptForPassword('Enter key store and key password: ')
        inputKeyPassword = inputStorePassword
    }
}

Add the following code to the start of the "android {" block so that you're only prompted for the password for release builds:

if (project.gradle.startParameter.taskNames.any { it.toLowerCase().contains('release') }) {
    promptForReleaseKeyPasswordHack()
}

Use the variables inputStorePassword and inputKeyPassword instead of the hardcoded '__unset' in the definition of signingConfigs.

Restart Gradle and remove the platforms/android/app/build directory (required, because once generated the signing-config.json file does not get overwritten).

After these hacks at least I'm able to build again for now.

robvandijk avatar Jul 24 '19 08:07 robvandijk