Notes

Using keytool for keystore management and app code signing

Generate a new keystore, or extract the certificate for an upload key

Edit on GitHub


Android
5 minutes
  • The app signing key never changes, but the upload key can be reset if the two are not the same (i.e. your signing key is different from your upload key)
  • To use the Android App Bundle format, you need to opt-in to Play App Signing
  • By using a separate upload key, you can request an upload key reset if the key is ever lost of compromised
  • It is recommended you generate your own keys, just in case you want to release the app to other marketplaces (e.g. Amazon Appstore, Samsung Galaxy Apps, F-Droid)
  • It is recommended you use two separate keys for app signing and upload (instead of making your app signing key your upload key).
  • We sign the app with upload key and then upload it to Google Play Console. Google then uses our upload certificate to verify our identity, sign our builds with app signing key and distributes them to devices.
App Signing KeyUpload key
Serves as master key, never changes during the lifetime of your app. Can not be reset if lost/stolenAn additional layer of security, can be reset if lost/stolen
Generated by us. Managed by Play ConsoleGenerated by us (optional). Managed by Play Console
Play Console manages and keeps this key and automatically signs the uploaded app for distributionKept by us

Generate a keystore

1keytool -genkeypair -v -keyalg RSA -keysize 4096 -validity 10000 -keystore KEYSTORE_OUTPUT_FILE.keystore -alias KEY_ALIAS

You’ll get a prompt for setting the keystore password and then asked for some additional info about yur organization. Next it’ll ask you for a password for your key Alias

  • -genkeypair generates a key pair (a public key and associated private key). It used to be named -genkey in earlier version and is still supported, but the new name -genkeypair is preferred going forward.
  • -keystore is the output file for your keystore, in this case KEYSTORE_NAME.keystore
  • -keysize is the size of the key, in this case 4096. Default is 2048 (when using -genkeypair and -keyalg is “RSA”)
  • -keyalg is the key algorithm, in this case RSA
  • -validity is in days. 9125 days is 25 years (default when you create a keystore with Android Studio). 10000 days is a little above 27 years.
  • -storetype is the format the keystore should be saved in. Default was JKS up till JDK 8. Newer versions use PKCS12.
  • -alias is the name of the key inside your keystore (one keystore can have multiple keys, you’d need to mention the alias of the key when you get to the signing part)

Script it

You can pass keystore password, alias key password, and organization details for a no-prompt key generation

1# pass keystore password and organizatiion details for no-prompt
2keytool -genkeypair -v -keyalg RSA -validity 10000 \
3  -dname "cn=FIRSTNAME LASTNAME, ou=ORGANIZATION_UNIT, o=ORGANIZATION, c=COUNTRY_CODE" \
4  -keystore "KEYSTORE_OUTPUT_FILE.keystore" -storepass "KEYSTORE_PASSWORD" -storetype "JKS" \
5  -alias "KEY_ALIAS" -keypass "KEY_ALIAS_PASSWORD"
  • -dname specifies details about your organization
  • -keypass will only be used if -storetype is provided and it’s not PKCS12 (default for JDK 9+). Since different store and key passwords not supported for PKCS12 KeyStores, your keystore password and your alias password will be the same and -keypass value will not be used.
1# pass keystore password and organization details for no-prompt
2keytool -genkeypair -v -keyalg RSA -validity 10000 \
3  -dname "cn=FIRSTNAME LASTNAME, ou=ORGANIZATION_UNIT, o=ORGANIZATION, c=COUNTRY_CODE" \
4  -keystore "KEYSTORE_OUTPUT_FILE.keystore" -storepass "KEYSTORE_PASSWORD" \
5  -alias "KEY_ALIAS"

Check keystore details

1keytool -list -keystore KEYSTORE_OUTPUT_FILE.keystore

It’ll prompt you for the password of your keystore and then output keystore details like what format it is, what’s the certificate fingerprint, and how many keys it contains

Enter keystore password:
Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 1 entry

key_alias, Jun 29, 2020, PrivateKeyEntry,
Certificate fingerprint (SHA-256): AA:BB:CC:1D:BB:C8:00:7B:35:12:12:21:21:12:12:12:12:12:34:56:78:90:E5:E5:A3:EB:1A:56:E3:2C:73:63

Export the certificate for the upload key to PEM format.

keytool command is a key and certificate management utility, it is part of JDK. You can use it to export the public certificate of your upload key.

1# extract the uplaod certificate
2keytool -export -rfc -keystore YOUR_UPLOAD_KEYSTORE.jks -alias UPLOAD_KEY_ALIAS -file OUTPUT_UPLOAD_CERTIFICATE.pem

Replace the following

  • YOUR_UPLOAD_KEYSTORE.jks - your keystore fiile
  • UPLOAD_KEY_ALIAS - your key alias
  • OUTPUT_UPLOAD_CERTIFICATE.pem - the output file name for the certificate
-exportcert
{-rfc}: Output in RFC style
{-alias alias}: Alias name of the entry to process
{-file file}: Output file name
{-keystore keystore}: Keystore name

Change the password for an Alias key

-keypasswd changes the password under which the private/secret key identified by alias is protected.

1# set new password for a private key
2keytool -keypasswd -alias KEY_ALIAS
1# set new password for a private key
2keytool -keypasswd -alias KEY_ALIAS -keypass OLD_KEY_PASSWORD -new NEW_KEY_PASSWORD
  • will change the password for the Alias KEY_ALIAS from OLD_KEY_PASSWORD to NEW_KEY_PASSWORD. You should leave these out though so that it prompts you to enter the password values instead of saving it in the command history.
  • password must be at least 6 characters
1keytool -keypasswd -keystore KEYSTORE_NAME.keystore -alias KEY_ALIAS -storepass KEYSTORE_PASSWORD -keypass OLD_KEY_PASSWORD -new NEW_KEY_PASSWORD
1keytool -keypasswd -keystore KEYSTORE_NAME.keystore -alias KEY_ALIAS -storepass KEYSTORE_PASSWORD
  • If the -keypass option is not provided at the command line, and the key password is different from the keystore password, then the user is prompted for it.
  • If the -new option is not provided at the command line, then the user is prompted for it

Change the password for the keystore

Similar to -keypasswd, you can use -storepasswd to change the keystore password

1keytool -storepasswd -keystore KEYSTORE_NAME.keystore
1keytool -storepasswd -keystore KEYSTORE_NAME.keystore -storepass OLD_STORE_PASSWORD -new OLD_STORE_PASSWORD

-keypasswd
{-alias alias}: Alias name of the entry to process
[-keypass old_keypass]: Key password
[-new new_keypass]: New password
{-keystore keystore}: Keystore name
{-storepass arg}: Keystore password

Convert JKS to PKCS12

You can convert a keystore in JKS format to PKCS12 with -importkeystore

1# import entries from a typical JKS type keystore key.jks into a PKCS12 keystore
2keytool -importkeystore -srckeystore appreactnative.jks -destkeystore appreactnative.keystore -deststoretype pkcs12
Importing keystore appreactnative.jks to appreactnative.keystore...
Enter destination keystore password:
Re-enter new password:
Enter source keystore password:
Enter key password for <xxxxxxxlc3BlbxxxxxxxxnBwcmVhY3Ruxxxxxxxx>
Entry for alias xxxxxxxlc3BlbxxxxxxxxnBwcmVhY3Ruxxxxxxxx successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled