Java Keystore Generate Aes Key

Posted on  by 

The Java KeyGenerator class (javax.crypto.KeyGenerator) is used to generate symmetric encryption keys. A symmetric encryption key is a key that is used for both encryption and decryption of data, by a symmetric encryption algorithm. In this Java KeyGenerator tutorial I will show you how to generate symmetric encryption keys.

  1. Java Keystore Generate Aes Key Generator
  2. Java Keystore Generate Aes Keyboard

Related

How To Set Up and Configure an OpenVPN Server on CentOS 8 Tutorial
How To Set Up a Firewall Using firewalld on CentOS 8 Tutorial

Introduction

Java Keytool is a key and certificate management tool that is used to manipulate Java Keystores, and is included with Java. A Java Keystore is a container for authorization certificates or public key certificates, and is often used by Java-based applications for encryption, authentication, and serving over HTTPS. Its entries are protected by a keystore password. A keystore entry is identified by an alias, and it consists of keys and certificates that form a trust chain.

This cheat sheet-style guide provides a quick reference to keytool commands that are commonly useful when working with Java Keystores. This includes creating and modifying Java Keystores so they can be used with your Java applications.

How to Use This Guide:

  • If you are not familiar with certificate signing requests (CSRs), read the CSR section of our OpenSSL cheat sheet
  • This guide is in a simple, cheat sheet format–self-contained command line snippets
  • Jump to any section that is relevant to the task you are trying to complete (Hint: use the Contents menu on the bottom-left or your browser’s Find function)
  • Most of the commands are one-liners that have been expanded to multiple lines (using the symbol) for clarity

Creating and Importing Keystore Entries

This section covers Java Keytool commands that are related to generating key pairs and certificates, and importing certificates.

Generate Keys in New/Existing Keystore

Use this method if you want to use HTTP (HTTP over TLS) to secure your Java application. This will create a new key pair in a new or existing Java Keystore, which can be used to create a CSR, and obtain an SSL certificate from a Certificate Authority.

This command generates a 2048-bit RSA key pair, under the specified alias (domain), in the specified keystore file (keystore.jks):

If the specified keystore does not already exist, it will be created after the requested information is supplied. This will prompt for the keystore password (new or existing), followed by a Distinguished Name prompt (for the private key), then the desired private key password.

Generate CSR For Existing Private Key

Use this method if you want to generate an CSR that you can send to a CA to request the issuance of a CA-signed SSL certificate. It requires that the keystore and alias already exist; you can use the previous command to ensure this.

This command creates a CSR (domain.csr) signed by the private key identified by the alias (domain) in the (keystore.jks) keystore:

After entering the keystore’s password, the CSR will be generated.

Import Signed/Root/Intermediate Certificate

Use this method if you want to import a signed certificate, e.g. a certificate signed by a CA, into your keystore; it must match the private key that exists in the specified alias. You may also use this same command to import root or intermediate certificates that your CA may require to complete a chain of trust. Simply specify a unique alias, such as root instead of domain, and the certificate that you want to import.

This command imports the certificate (domain.crt) into the keystore (keystore.jks), under the specified alias (domain). If you are importing a signed certificate, it must correspond to the private key in the specified alias:

You will be prompted for the keystore password, then for a confirmation of the import action.

Note: You may also use the command to import a CA’s certificates into your Java truststore, which is typically located in $JAVA_HOME/jre/lib/security/cacerts assuming $JAVA_HOME is where your JRE or JDK is installed.

Generate Self-Signed Certificate in New/Existing Keystore

Use this command if you want to generate a self-signed certificate for your Java applications. This is actually the same command that is used to create a new key pair, but with the validity lifetime specified in days.

This command generates a 2048-bit RSA key pair, valid for 365 days, under the specified alias (domain), in the specified keystore file (keystore.jks):

If the specified keystore does not already exist, it will be created after the requested information is supplied. This will prompt for the keystore password (new or existing), followed by a Distinguished Name prompt (for the private key), then the desired private key password.

Viewing Keystore Entries

This section covers listing the contents of a Java Keystore, such as viewing certificate information or exporting certificates.

Java Keystore Generate Aes Key

List Keystore Certificate Fingerprints

This command lists the SHA fingerprints of all of the certificates in the keystore (keystore.jks), under their respective aliases:

You will be prompted for the keystore’s password. You may also restrict the output to a specific alias by using the -alias domain option, where “domain” is the alias name.

List Verbose Keystore Contents

This command lists verbose information about the entries a keystore (keystore.jks) contains, including certificate chain length, fingerprint of certificates in the chain, distinguished names, serial number, and creation/expiration date, under their respective aliases:

You will be prompted for the keystore’s password. You may also restrict the output to a specific alias by using the -alias domain option, where “domain” is the alias name.

Note: You may also use this command to view which certificates are in your Java truststore, which is typically located in $JAVA_HOME/jre/lib/security/cacerts assuming $JAVA_HOME is where your JRE or JDK is installed.

Use Keytool to View Certificate Information

This command prints verbose information about a certificate file (certificate.crt), including its fingerprints, distinguished name of owner and issuer, and the time period of its validity:

You will be prompted for the keystore password.

Export Certificate

This command exports a binary DER-encoded certificate (domain.der), that is associated with the alias (domain), in the keystore (keystore.jks):

You will be prompted for the keystore password. If you want to convert the DER-encoded certificate to PEM-encoding, follow our OpenSSL cheat sheet.

Modifying Keystore

This section covers the modification of Java Keystore entries, such as deleting or renaming aliases.

Change Keystore Password

This command is used to change the password of a keystore (keystore.jks):

You will be prompted for the current password, then the new password. You may also specify the new password in the command by using the -new newpass option, where “newpass” is the password.

Delete Alias

This command is used to delete an alias (domain) in a keystore (keystore.jks):

You will be prompted for the keystore password.

Java

Rename Alias

This command will rename the alias (domain) to the destination alias (newdomain) in the keystore (keystore.jks):

You will be prompted for the keystore password.

Conclusion

That should cover how most people use Java Keytool to manipulate their Java Keystores. It has many other uses that were not covered here, so feel free to ask or suggest other uses in the comments.

This tutorial is based on the version of keystore that ships with Java 1.7.0 update 65. For help installing Java on Ubuntu, follow this guide.

Overview

Security has become a great topic of discussion in the last few years due to the recent releasing of documents from Edward Snowden and the explosion of hacking against online commerce stores like JC Penny, Sony and Target. While this post will not give you all of the tools to help prevent the use of illegally sourced data, this post will provide a starting point for building a set of tools and tactics that will help prevent the use of data by other parties.

This post will show how to adopt AES encryption for strings in a Java environment. It will talk about creating AES keys and storing AES keys in a JCEKS keystore format. A working example of the code in this blog is located at https://github.com/mike-ensor/aes-256-encryption-utility

It is recommended to read each section in order because each section builds off of the previous section, however, this you might want to just jump quickly jump to a particular section.

  • Setup - Setup and create keys with keytool
  • Encrypt - Encrypt messages using byte[] keys
  • Decrypt - Decrypt messages using same IV and key from encryption
  • Obtain Keys from Keystore - Obtain keys from keystore via an alias

What is JCEKS?

JCEKS stands for Java Cryptography Extension KeyStore and it is an alternative keystore format for the Java platform. Storing keys in a KeyStore can be a measure to prevent your encryption keys from being exposed. Java KeyStores securely contain individual certificates and keys that can be referenced by an alias for use in a Java program. Java KeyStores are often created using the 'keytool' provided with the Java JDK.

NOTE: It is strongly recommended to create a complex passcode for KeyStores to keep the contents secure. The KeyStore is a file that is considered to be public, but it is advisable to not give easy access to the file.

Setup

All encryption is governed by laws of each country and often have restrictions on the strength of the encryption. One example is that in the United States, all encryption over 128-bit is restricted if the data is traveling outside of the boarder. By default, the Java JCE implements a strength policy to comply with these rules. If a stronger encryption is preferred, and adheres to the laws of the country, then the JCE needs to have access to the stronger encryption policy. Very plainly put, if you are planning on using AES 256-bit encryption, you must install the Unlimited Strength Jurisdiction Policy Files. Without the policies in place, 256-bit encryption is not possible.

Example

Installation of JCE Unlimited Strength Policy

This post is focusing on the keys rather than the installation and setup of the JCE. The installation is rather simple with explicit instructions found here (NOTE: this is for JDK7, if using a different JDK, search for the appropriate JCE policy files).

Java Keystore Generate Aes Key Generator

Keystore Setup

When using the KeyTool manipulating a keystore is simple. Keystores must be created with a link to a new key or during an import of an existing keystore. In order to create a new key and keystore simply type:

Important Flags

In the example above here are the explanations for the keytool's parameters:

Keystore Parameters

genseckey
Generate SecretKey. This is the flag indicating the creation of a synchronous key which will become our AES key
keystore
Location of the keystore. If the keystore does not exist, the tool will create a new store. Paths can be relative or absolute but must be local
storetype
this is the type of store (JCE, PK12, JCEKS, etc). JCEKS is used to store symmetric keys (AES) not contained within a certificate.
storepass
password related to the keystore. Highly recommended to create a strong passphrase for the keystore

Key Parameters

keyalg
algorithm used to create the key (AES/DES/etc)
keysize
size of the key (128, 192, 256, etc)
alias
alias given to the newly created key in which to reference when using the key
keypass
password protecting the use of the key

Encrypt

As it pertains to data in Java and at the most basic level, encryption is an algorithmic process used to programmatically obfuscate data through a reversible process where both parties have information pertaining to the data and how the algorithm is used. In Java encryption, this involves the use of a Cipher. A Cipher object in the JCE is a generic entry point into the encryption provider typically selected by the algorithm. This example uses the default Java provider but would also work with Bouncy Castle.

Generating a Cipher object

Obtaining an instance of Cipher is rather easy and the same process is required for both encryption and decryption. (NOTE: Encryption and Decryption require the same algorithm but do not require the same object instance)Once we have an instance of the Cipher, we can encrypt and decrypt data according to the algorithm. Often the algorithm will require additional pieces of information in order to encrypt/decrypt data. In this example, we will need to pass the algorithm the bytes containing the key and an initial vector (explained below).

Initialization

In order to use the Cipher, we must first initialize the cipher. This step is necessary so we can provide additional information to the algorithm like the AES key and the Initial Vector (aka IV).

Parameters

The SecretKeySpecification is an object containing a reference to the bytes forming the AES key. The AES key is nothing more than a specific sized byte array (256-bit for AES 256 or 32 bytes) that is generated by the keytool (see above).

Alternative Parameteters

There are multiple methods to create keys such as a hash including a salt, username and password (or similar). This method would utilize a SHA1 hash of the concatenated strings, convert to bytes and then truncate result to the desired size. This post will not show the generation of a key using this method or the use of a PBE key method using a password and salt. The password and/or salt usage for the keys is handled by the keytool using the inputs during the creation of new keys.

Initialization Vector

The AES algorithm also requires a second parameter called the Initialiation Vector. The IV is used in the process to randomize the encrypted message and prevent the key from easy guessing. The IV is considered a publicly shared piece of information, but again, it is not recommended to openly share the information (for example, it wouldn't be wise to post it on your company's website). When encrypting a message, it is not uncommon to prepend the message with the IV since the IV will be a set/known size based on the algorithm. NOTE: the AES algorithm will output the same result if using the same IV, key and message. It is recommended that the IV be randomly created each time an encryption takes place.

With the newly initialized Cipher, encrypting a message is simple. Simply call:

Encoding Results

Byte arrays are difficult to visualize since they often do not form characters in any charset. The best recommendation to solve this is to represent the bytes in HEX (base-16), Double HEX (base-32) or Base64 format. If the message will be passed via a URL or POST parameter, be sure to use a web-safe Base64 encoding. Google Guava library provides a excellent BaseEncoding utility. NOTE: Remember to decode the encoded message before decrypting.

Decrypt

Decrypting a message is almost a reverse of the encryption process with a few exceptions. Decryption requires a known initialization vector as a parameter unlike the encryption process generating a random IV.

Java Keystore Generate Aes Keyboard

Decryption

When decrypting, obtain a cipher object with the same process as the encryption method. The Cipher object will need to utilize the exact same algorithm including the method and padding selections. Once the code has obtained a reference to a Cipher object, the next step is to initialize the cipher for decryption and pass in a reference to a key and the initialization vector.NOTE: The key is stored in the keystore and obtained by the use of an alias. See below for details on obtaining keys from a keystore

Once the cipher has been provided the key, IV and initialized for decryption, the cipher is ready to perform the decryption.

Strategies to keep IV

The IV used to encrypt the message is important to decrypting the message therefore the question is raised, how do they stay together. One solution is to Base Encode (see above) the IV and prepend it to the encrypted and encoded message: Base64UrlSafe(myIv) + delimiter + Base64UrlSafe(encryptedMessage). Other possible solutions might be contextual such as including an attribute in an XML file with the IV and one for the alias to the key used.

Obtain Key from Keystore

The beginning of this post has shown how easy it is to create new AES-256 keys that reference an alias inside of a keystore database. The post then continues on how to encrypt and decrypt a message given a key, but has yet shown how to obtain a reference to the key in a keystore.

Solution

Parameters

keystoreLocation
String - Location to local keystore file location
keypass
String - Password used when creating or modifying the keystore file with keytool (see above)
alias
String - Alias used when creating new key with keytool (see above)

Conclusion

This post has shown how to encrypt and decrypt string based messages using the AES-256 encryption algorithm. The keys to encrypt and decrypt these messages are held inside of a JCEKS formatted KeyStore database created using the JDK provided 'keytool' utility. The examples in this post should be considered a solid start to encrypting/decrypting symmetric keys such as AES. This should not be considered the only line of defense when encrypting messages, for example key rotation. Key rotation is a method to mitigate risks in the event of a data breach. If an intruder obtains data and manages to hack a single key, the data contained in multiple files should have used several keys to encrypt the data thus bringing down risk of a total exposure loss.

All of the examples in this blog post have been condensed into a simple tool allowing for the viewing of keys inside of a keystore, an operation that is not supported out of the box by the JDK keytool. Each aspect of the steps and topics outlined in this post are available at: https://github.com/mike-ensor/aes-256-encryption-utility. NOTE: The examples, sample code and any reference is to be used at the sole implementers risk and there is no implied warranty or liability, you assume all risks.

Coments are closed