30

Up until now I had been signing my apks with the following method:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore {keystore-file} {apk-file} {keystore-alias}

However I am trying to use the new apksigner tool and I cannot get it to work since it always tells me the password is invalid. Which is impossible because I have done it multiple times, with the jarsigner works and with the apksigner doesn't. The commands I have tried are the following:

apksigner sign --ks {keystore-file} {apk-file}

apksigner sign --ks {keystore-file} --ks-key-alias {keystore-alias} {apk-file}

Now the weirdest part comes when I created a new keystore to test this, and with this new keystore it's working. So I don't understand what is the difference. Here's the information obtained from calling "keytool -v -list -keystore {keystore-file}" on both.

Production keystore (I have removed some text in case this is dangerous):

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: {keystore-alias}
Creation date: Apr 4, 2016
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN={removed-text}, OU={removed-text}, O={removed-text}, L=Unknown, ST=Unknown, C=Unknown
Issuer: CN={removed-text}, OU={removed-text}, O={removed-text}, L=Unknown, ST=Unknown, C=Unknown
Serial number: {removed-text}
Valid from: Mon Apr 04 12:39:50 CEST 2016 until: Fri Aug 21 12:39:50 CEST 2043
Certificate fingerprints:
     MD5:  {removed-text}
     SHA1: {removed-text}
     SHA256: {removed-text}
     Signature algorithm name: SHA256withRSA
     Version: 3

Extensions: 

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: {removed-text}
0010: {removed-text} {removed-text}                                        ....
]
]



*******************************************
*******************************************

New test keystore:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: app
Creation date: Nov 17, 2016
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Foobar, OU=Foobar, O=foobar, L=Unknown, ST=Unknown, C=Unknown
Issuer: CN=Foobar, OU=Foobar, O=foobar, L=Unknown, ST=Unknown, C=Unknown
Serial number: 448c7afc
Valid from: Thu Nov 17 11:40:26 CET 2016 until: Mon Apr 04 12:40:26 CEST 2044
Certificate fingerprints:
     MD5:  3E:29:C0:3C:30:B4:DC:E0:A5:94:1D:2E:E9:86:58:CA
     SHA1: 3D:09:B4:42:A2:7C:14:C7:3E:54:33:0E:AB:75:2E:F1:19:23:00:FA
     SHA256: 7F:E0:51:F1:6A:53:45:56:42:B9:F9:38:92:69:81:7A:DA:71:FF:44:51:15:7F:F9:B4:1C:AA:2B:53:4A:89:72
     Signature algorithm name: SHA256withRSA
     Version: 3

Extensions: 

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: BC 1B E6 C4 6D 25 01 70   CA AC 81 34 81 4B AE 41  ....m%.p...4.K.A
0010: 10 DF D8 13                                        ....
]
]



*******************************************
*******************************************
Noel De Martin
  • 2,779
  • 4
  • 28
  • 39
  • What's the error message / exception that you are getting form apksigner? Also, does providing the password to apksigner via --ks-pass pass: and --key-pass pass: in different combinations change anything? Try --ks-pass and no --key-pass, and --key-pass and no --ks-pass. – Alex Klyubin Nov 18 '16 at 14:09
  • @AlexKlyubin Ok, so the error I was getting was a simple "Password verification failed", but after trying what you said, providing the password in the cmd, I got "Unsupported password spec for Keystore password". I don't know which is the spec for passwords, but I changed the password to a simpler version (without special characters) and now it works. I don't understand why would they change the format. Anyways this solves my problem, so if you want to move the comment to an answer I will mark it as accepted. If you can shed some light on why this happens it'd be a good plus :D. Thank you. – Noel De Martin Nov 21 '16 at 08:30
  • I'm glad to hear you found a workaound. Did you strip out the special characters or replace them with ASCII-equivalents (e.g., "a with umlaut" becomes "a")? – Alex Klyubin Nov 23 '16 at 10:58
  • I stripped them and I am using a password with only alphanumeric characters. – Noel De Martin Nov 23 '16 at 18:00
  • I believe I figured it out. I have now filed https://code.google.com/p/android/issues/detail?id=234089 to track the issue and am working on a fix/workaround. This issue in keytool/jarsigner may also explain similar issued with Android Plugin for Gradle / Android Studio being unable to use some keystores, reporting the password is wrong. – Alex Klyubin Feb 14 '17 at 02:35

5 Answers5

48

use it this way

./apksigner sign --ks test.jks --ks-key-alias test --ks-pass pass:testtest --key-pass pass:testtest Test_Aligned.apk
max
  • 5,963
  • 12
  • 49
  • 80
20

I cannot vote/comment yet, but +1 for max's fix:

./apksigner sign --ks test.jks --ks-key-alias test --ks-pass pass:testtest --key-pass pass:testtest Test_Aligned.apk

Prefixing my passwords with "pass:" worked for me

--ks-pass pass:MyPassword
--key-pass pass:MyPassword
Paul M
  • 351
  • 3
  • 14
17

Here's what worked for me, I changed this:

--ks-pass "MyPassword"

To this:

--ks-pass pass:"MyPassword"

A weird API to work with... but it worked!

Ben Winding
  • 10,208
  • 4
  • 80
  • 67
14

Wow, I didn't know you could change passwords in the keystore.

Anyway I had this exact problem and it turns out you don't need to change your password. The trick is to set options

--ks-pass stdin --key-pass stdin

This is supposedly default behavior but in my case it only worked if I specifically included these.

Execute the command, you'll be asked to enter passwords, and it works even with characters such as !.

Nemanja Kovacevic
  • 3,510
  • 2
  • 30
  • 45
  • 1
    Unfortunately I have tried it and still doesn't work, I am using the character ¡ in this case, but I still think it's frustrating that this is not documented anywhere that I could find. Still jarsigner is working with the same password, so it isn't a problem of the password. – Noel De Martin Jan 20 '17 at 08:44
  • 1
    Worked for me, can't think of a way how this could happen if they did implement the value `stdin` as "default". – Hai Zhang Mar 31 '17 at 11:28
6

The original answer can be found on the comments of the question, I am moving it here in order to mark the question as answered.

Although I am still not sure 100% of the details, the problem was the password I was using for my keystore contained special characters (* and !). After changing the password to an alphanumeric format, the problem was solved. So it seems like apksigner does not accept the same format for passwords than jarsigner.

Noel De Martin
  • 2,779
  • 4
  • 28
  • 39