Using keytool for keystore management and app signing

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

Generate a keystore

keytool -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

# pass keystore password and organizatiion details for no-prompt
keytool -genkeypair -v -keyalg RSA -validity 10000 \
  -dname "cn=FIRSTNAME LASTNAME, ou=ORGANIZATION_UNIT, o=ORGANIZATION, c=COUNTRY_CODE" \
  -keystore "KEYSTORE_OUTPUT_FILE.keystore" -storepass "KEYSTORE_PASSWORD" -storetype "JKS" \
  -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.
# pass keystore password and organization details for no-prompt
keytool -genkeypair -v -keyalg RSA -validity 10000 \
  -dname "cn=FIRSTNAME LASTNAME, ou=ORGANIZATION_UNIT, o=ORGANIZATION, c=COUNTRY_CODE" \
  -keystore "KEYSTORE_OUTPUT_FILE.keystore" -storepass "KEYSTORE_PASSWORD" \
  -alias "KEY_ALIAS"

Check keystore details

keytool -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.

# extract the uplaod certificate
keytool -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.

# set new password for a private key
keytool -keypasswd -alias KEY_ALIAS
# set new password for a private key
keytool -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
keytool -keypasswd -keystore KEYSTORE_NAME.keystore -alias KEY_ALIAS -storepass KEYSTORE_PASSWORD -keypass OLD_KEY_PASSWORD -new NEW_KEY_PASSWORD
keytool -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

keytool -storepasswd -keystore KEYSTORE_NAME.keystore
keytool -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

# import entries from a typical JKS type keystore key.jks into a PKCS12 keystore
keytool -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

Links

Please note that this site and the posts on it are, and will always be, a work in progress. If i waited for perfection, i’d never get anything done.