The Java ‘keytool’ command, keystore files, and certificates

Java keytool/keystore FAQ: Can you share some Java keytool and keystore command examples?

Sure. As a little bit of background, in creating my "Hyde (Hide Your Mac Desktop)" software application, I decided to venture into the world of commercial software, selling my app for a whopping 99 cents. While that price is trivial, creating the “software licensing” code for this application was anything but trivial.

I finally decided to use a Java licensing tool named TrueLicense to assist with the software licensing, and TrueLicense quickly led me down the path of learning about the Java keytool and keystore path. So that’s what this article is about: How to use the Java keytool command to work with private and public keys, and work with intermediate certificate files.

Java and TrueLicense public key, private key background

If you've never used a tool like TrueLicense before, it's important to understand how it works, so you can understand the need for the Java keytool commands below. I won't go into great detail on this, but these are the basic points behind TrueLicense:

  • You create a private key keystore, which you never (ever) give to anyone. As they mention in this article on android.com, “A keystore is a binary file that contains a set of private keys. You must keep your keystore in a safe and secure place.”
  • You work through a couple of steps to distribute a public key keystore with your application.
  • When a customer buys a software license for your application, you create that license file however you want to, and then sign the license with your private key. (I don’t show that Java code here, but I do show it in other articles.)
  • You send the signed license file to your customer.
  • The application you've given your customer must be smart enough to import this signed license file into its environment. This again requires Java code, which I’ve shared in other articles.

How this normally works

During this process, I think it's also important to note how the digital signing process normally works, i.e., when you're not taking all these steps for a tool like TrueLicense.

In the "normal" process, two people are usually involved: 1) the person who wants to share their public key, and 2) the person who wants to use the first person's public key.

Usually the first person (the “share-er”) does these tasks:

  • Create the private key keystore file.
  • Export the certificate file from the private key keystore.
  • Sends the certificate to the second person.

Then, the second person normally does this task:

  • Imports the certificate from the first person into their public key keystore.

Because of the way the TrueLicense software licensing process works, I'm showing one person doing all these tasks here. But if you get confused in the process, just come back to this section, and remember that two people are normally involved in this process.

Java keytool and keystore tasks in this tutorial

In the remainder of this tutorial I'll demonstrate the following keytool tasks:

  • How to create a keystore that contains a private key.
  • How to create a temporary certificate from that private keystore.
  • How to use that certificate to generate a public key keystore.
  • How to query and verify your keystores with the keytool command.

Create private key and keystore

To get started, the first thing we need to do is create a private key keystore. This is going to be a file on your filesystem, and I'm going to name mine privateKey.store. To create this “private key keystore,”  run the following keytool command:

$ keytool -genkey -alias ftpKey -keystore privateKey.store

This keytool command can be read as:

  • I want to generate a new private key (genkey)
  • I want to create an alias for this key named "ftpKey"
  • I want to store this information in the file named privateKey.store

After you issue this command, keytool prompts you with the following questions. I have provided my own example answers to these prompts so you can see exactly how this works.

(Note: In the commands that follow, the text that the user types is shown in a bold font.)

$ keytool -genkey -alias ftpKey -keystore privateKey.store

Enter keystore password:  foobar
What is your first and last name?
  [Unknown]:  Alvin Alexander
What is the name of your organizational unit?
  [Unknown]:  Application Development
What is the name of your organization?
  [Unknown]:  devdaily.com
What is the name of your City or Locality?
  [Unknown]:  Louisville
What is the name of your State or Province?
  [Unknown]:  KY
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=Alvin Alexander, OU=Application Development, O=devdaily.com, L=Louisville, ST=KY, C=US correct?
  [no]:  yes

Enter key password for <ftpKey>
      (RETURN if same as keystore password):  123xyz

There are at least a few important points to note here:

  • The password for accessing the keystore file is "foobar".
  • The password for my ftpKey alias is "123xyz".

Both of these passwords are very important, and you'll see how they are used in the next steps.

Generate a temporary certificate file

Remember that our end game is to generate a keystore that contains our public key. To do that, we have to take an intermediate step of creating a "certificate file" from our private keystore. To create this certificate file, use this keytool command:

$ keytool -export -alias ftpKey -file certfile.cer -keystore privateKey.store

This command can be read like this: “Export the information for the alias ‘ftpKey’ to the file named ‘certfile.cer,‘ getting the information you need from the file named privateKey.store.”

Here’s how this command works when I run it from my command line:

$ keytool -export -alias ftpKey -file certfile.cer -keystore privateKey.store

Enter keystore password:  foobar
Certificate stored in file <certfile.cer>

As you can see, you don't have to do too much there, but you must know the password for your private key keystore (the privateKey.store file).

Import this certificate into a new public keystore

Now that you have this intermediate certificate file, you can create your public key keystore file from it, using this command:

$ keytool -import -alias publicFtpCert -file certfile.cer -keystore publicKey.store

This command can be read as: “Import the alias named ‘publicFtpCert’ from the file named certfile.cer, and store this information in the file named publicKey.store.”

When I run this keytool command from the command line, the process looks like this:

$ keytool -import -alias publicCertFromAl -file certfile.cer -keystore publicKey.store

Enter keystore password:  BARBAZ
Owner: CN=Alvin Alexander, OU=Application Development, O=devdaily.com, L=Louisville, ST=KY, C=US
Issuer: CN=Alvin Alexander, OU=Application Development, O=devdaily.com, L=Louisville, ST=KY, C=US
Serial number: 4bd4e793
Valid from: Sun Apr 25 17:08:35 AKDT 2010 until: Sat Jul 24 17:08:35 AKDT 2010
Certificate fingerprints:
       MD5:  55:20:B2:68:FD:0F:4E:BF:D5:E5:D5:04:47:6C:E3:10
       SHA1: 25:17:A0:CA:86:CC:3E:6C:2D:C0:4E:8D:E8:33:05:F7:4B:50:FE:E5
Trust this certificate? [no]:  yes
Certificate was added to keystore

A few important points here:

  • The alias used here (publicCertFromAl) does not have to correspond to the alias used when the private key keystore and certificate file were created. This alias will be stored as an “alias name” in your public keystore file.
  • This command either (a) creates the file named publicKey.store if it doesn't exist, or (b) adds the information for this alias to that file if it already exists. For my needs, I created a new file.
  • The password shown above is the password for the new keystore we’re creating, publicKey.store. It should be different than the password used for your private key keystore.
  • You might run this command in a number of different scenarios. For instance, if you maintained your own public key keystore, and you regularly receive certificates from people you know who want to sign their documents, you'll use this command to import their certificate into your keystore. In this scenario, your friends will run the "keygen" and "export" commands shown above, and you will run the "import" command shown here.

Also, at this point you no longer need the intermediate certificate file, so you can delete it:

$ rm certfile.cer

How to view information about a keystore (keytool list)

Technically that's all you need to know to (a) create a private keystore, (b) export a certificate for an alias in your private keystore, and (c) import that certificate into your keystore of known public certificates, but ... it's also very nice to be able to query a keystore to see what it contains. To do that, you use the "list" option of the keytool command, like this:

$ keytool -list -v -keystore privateKey.store

Assuming you know the password for the keystore named privateKey.store, the process looks like this:

$ keytool -list -v -keystore privateKey.store

Enter keystore password:  foobar

Keystore type: jks
Keystore provider: SUN

Your keystore contains 2 entries

Alias name: ftpkey
Creation date: Apr 25, 2010
Entry type: keyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Alvin Alexander, OU=Application Development, O=devdaily.com, L=Louisville, ST=KY, C=US
Issuer: CN=Alvin Alexander, OU=Application Development, O=devdaily.com, L=Louisville, ST=KY, C=US
Serial number: 4bd4e793
Valid from: Sun Apr 25 17:08:35 AKDT 2010 until: Sat Jul 24 17:08:35 AKDT 2010
Certificate fingerprints:
	 MD5:  55:20:B2:68:FD:0F:4E:BF:D5:E5:D5:04:47:6C:E3:10
	 SHA1: 25:17:A0:CA:86:CC:3E:6C:2D:C0:4E:8D:E8:33:05:F7:4B:50:FE:E5

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

As you can see, this "keytool list" command shows a lot of information about your keystore. I won't add much to it here, you can read through those contents. But I will add this: If your keystore contains more than one alias, the output for each alias would be shown by this list command, and the output for each alias will look just like the output shown above.

Another example of creating a keystore

I’ve been working with Android a little bit lately, and when you want to release an app to the Android/Google Play Store, you need to sign your app. At the bottom of this page Google recommends using this keytool command to create a keystore file:

keytool -genkey -v -keystore foo.keystore -alias foo -keyalg RSA -keysize 2048 -validity 10000

I quote from their page, “This example prompts you for passwords for the keystore and key, and to provide the Distinguished Name fields for your key. It then generates the keystore as a file called foo.keystore. The keystore contains a single key, valid for 10000 days. The alias is a name that you will use later when signing your app.”

I changed their longer names to “foo,” but that gives you another example of how this works.

Java keytool and keystore commands - summary

There is much more to be written about the Java keytool command and keystore files, but I'll leave this tutorial at this point until anyone has a question.