The
canonmill package provides a
Keystore
implementation designed to be less painful from an operational perspective
than any of the
Keystore
implementations included in the standard JDK.
The package does not support encryption of the keystore with a password, or
encryption of the keystore entries with passwords. In the author's opinion,
this offers no real security. To elaborate, keystore encryption is intended
to ensure that private keys are encrypted at rest so that, in the event of a
compromise, the private keys cannot be used by an attacker. Unfortunately,
this is ineffectual for a couple of reasons. Firstly, because nobody wants
to have to manually type in a password each time their server-based Java
application starts, the password is typically stored along with the
application configuration. This means if an attacker compromises the
application, they have both the keys and the passwords anyway. Secondly, if
an application is compromised and the keystore is stolen, the keys within
the keystore are going to have to be blacklisted and reissued anyway, so
"protecting" them with a passphrase is of very little utility.
Use the following
Maven
dependency:
To use the canonmill keystore, it's first
necessary to create a directory that will contain PEM-encoded private keys
and certificates. It's then necessary to create an index file that maps
aliases to keys/certificates.
An an example, assume the following files exist:
Now, all of these files could be placed in a directory
/etc/certs. We can now create the index file and place it anywhere
the application wants it to be. The index file has a strictly-defined XML
format with a schema. An example index file might look like this:
Each Key and
Certificate
entry assigns an alias to a key or certificate, respectively. The
filenames given are resolved relative to the directory given by the
BaseDirectory
attribute.
To load a keystore, the standard Keystore API
should be used. Assuming that the keystore's XML index file exists
at file:
The CMKeyStoreProvider class is registered using
the name
CANONMILL
as service of type
java.security.Provider
and so can be used in the same manner as any other provider in the JDK
security API.
The standard keystore API provides methods to reload
KeyStore values at any time. Unfortunately,
other parts of the security API such as the
SSLContext will cache the keys and certificates
internally and so reloading the KeyStore
is ineffective.
The CMKeyStores class contains convenience
methods to construct an SSLContext for use
in applications, and to reload any given
SSLContext.
The XML schema for the keystore's index file is as follows: