The main uses of cryptographic keys in the product are SSL (see section Secure Sockets Layer (SSL) Support) and encryption (see section TDI Server Instance Security).
SSL and asymmetric encryption algorithms such as RSA (which is the default encryption algorithm of the Server) use public/private keys. Public and private keys have a one-to-one correspondence - matching public and private keys are called a "key pair".
Normally inside a keystore a public key comes wrapped in an X.509 certificate. Most keystore operations actually involve the whole public key certificate and not only the public key.
Again in most cases inside a keystore a private key is accompanied by the corresponding public key certificate.
Secret keys are used by symmetric encryption algorithms such as DES, AES and RC4. Note that some keystore formats such as JKS and PKCS#12 do not support secret keys.
We cannot use secret keys for SSL (the SSL protocol actually generates secret keys on the fly, but normally we don't have control over them).
A keystore, as the name implies, provides storage for keys. It can be a file or a hardware device. The most popular keystore file formats used by Java programs are JKS, JCEKS and PKCS#12. See the following table for comparison:
Keystore file format | Origin | Store public/private keys and certificates | Store secret keys |
---|---|---|---|
JKS | Proprietary | Yes | No |
JCEKS | Proprietary | Yes | Yes |
PKCS#12 | Standard | Yes | No |
Note that the only one of the above keystore formats that can store secret keys is JCEKS. Also in general JCEKS offers greater protection than JKS. JKS, JCEKS and PKCS#12 keystores are protected by a password. Furthermore, each private or secret key inside a keystore can be protected by an individual password. Public key certificates do not have passwords, because normally there is no need to keep them secret.
To use SSL we need to provide a set of public/private keys. You cannot use secret keys for SSL.
An SSL connection has two sides - the SSL server side and the SSL client side. Each side has two keystores - an SSL keystore and an SSL truststore. Note that the word "keystore" is used both to mean a store of keys and an SSL keystore. So SSL keystore and SSL truststore are both keystores. In fact, the SSL keystore and the SSL truststore are only logical roles and it is perfectly legal to use the same physical keystore file for both. The SSL keystore contains a private key that is used to prove the authenticity of this SSL side to the other side of an SSL connection. The SSL truststore contains public key certificates of trusted parties.
If you are using the default properties to configure SSL (javax.net.ssl.*), the SSL keystore should contain exactly one private key, because there is no way to specify which key will be used.
For encryption we have two alternatives:
For public key encryption the most popular algorithm is RSA. Note that other popular public key algorithms such as DiffieHellman (key exchange) and DSA (digital signature) cannot be used for encryption.
Generally encryption with secret keys is much faster and much more secure than encryption with public keys. However, by default the Directory Integrator Server uses public key encryption with RSA to preserve backward compatibility
The IBM JVM provides two utilities for working with keys and certificates - keytool and Ikeyman. keytool is a command-line utility that is popular in the Java community. Ikeyman is a GUI tool from IBM, which provides many of the features of 'keytool'. Both tools are located in the TDI_install_dir/jvm/jre/bin folder. For detailed information about these tools see the documentation of the IBM JVM: http://www.ibm.com/developerworks/java/jdk/security/
Default keystores shipped with the product:
Keystore location | Keystore password | Trusted public keys | Private keys |
---|---|---|---|
TDI_install_dir/testserver.jks | server | admin | server |
TDI_install_dir/serverapi/testadmin.jks | administrator | server | admin |
Use the list command of keytool. For example the following command lists information about the keys (alias and type) inside the keystore file mystore.jck; the format of the keystore is JCEKS and its password is "mystorepass":
The distinguished name of the owner of the certificate is "cn=myserver.mydomain.com", which should be the same as the DNS name of the server that will use the self-signed certificate for SSL (for public key encryption the content of the certificate does not matter much). The certificate is valid for 365 days. The size of the generated RSA key is 1024 bytes. The password of the private key is "mykeypass". The key pair is stored in a keystore file mystore.jck with format JCEKS (if the file does not exist, it will be created). The password of the keystore is "mystorepass".
The mystore.jck keystore can be used as an SSL keystore of a server program that runs on the "myserver.mydomain.com" host. The keystore also contains a public key certificate for the private key, so it can be used as an SSL truststore for clients that connect to the server on "myserver.mydomain.com". (Although to give your private key to clients is completely unnecessary and generally a bad security practice.)
First a key pair and a self-signed certificate is generated (see section "Generate a public/private key pair and a self-signed certificate"). After that a certificate for the public key is requested from a Certification Authority. When the Certification Authority sends back the signed certificate, the certificate is imported into the appropriate truststore, replacing the self-signed certificate.
For example using keytool we can generate a Certificate Signing Request for the "myserverkey" key from the mystore.jck keystore like this:
This command creates a Certificate Signing Request in the myRequest.csr file for the public key with alias "myserverkey". The created Certificate Signing Request now can be sent to a Certification Authority. When the new certificate arrives, we can import it in the keystore as described in section "Import public key certificate in a keystore". The following keytool command generates a 256 bit AES key with alias "myseckey":
The new key is stored in a JCEKS keystore file mystore.jck with password "mystorepass". The password that protects the secret key is "mykeypass".
The copy will be stored under alias "myotherserverkey" in the JKS keystore file myotherstore.jks (if it does not exist the file will be created).
The command will eventually ask for the password of each individual private or secret key inside the source keystore. Note that JKS and PKCS#12 keystores cannot hold secret keys. You should not try to convert a keystore that contains secret keys to either JKS or PKCS#12.
The resulting .der file contains the DER encoding of the X.509 certificate. It is a binary file. To get the same binary data in text form (base-64 encoded form of the DER encoding of the X.509 certificate) use the "-rfc" option of keytool:
keytool will attempt to verify the signer of the certificate which you are trying to import. This means constructing a certificate chain from the imported certificate to some other trusted certificate. If a chain cannot be established, keytool will ask you whether you are certain that the certificate needs to be imported.
To import a certificate that is a response from a Certificate Authority to a Certificate Signing Request (this means you already have a private key in the keystore for that certificate) use a command like this:
Note that when you import a certificate for an existing private key, we have to specify the password of the private key. keytool will attempt to verify the signer of the certificate by constructing a certificate chain to a trusted certificate. If a chain cannot be established, the import will fail - we will not be asked to verify the authenticity of the certificate. To have a successful import of an answer to a Certificate Signing Request, we have to trust the Certificate Authority which issued the certificate. If your Certificate Authority is one of the popular ones (for example, VeriSign or Thawte) you could rely on the certificates in the default truststore of the JVM (java.home/lib/security/cacerts) by using the "-trustcacerts" option of keytool:
The above operation will generate a new self-signed certificate, that has the same DN, SIGALG, KEYS as the original certificate but has a new SERIAL NUMBER and VALIDITY period.
The generated new certificate will automatically replace the original one.
So if we need the original one later for reference or for any reason, keep a copy of the original keystore before doing the certificate extension explained above.Note that this works only for self-signed certificates. It actually generates a new self-signed certificate for the public key, so we need to export it and update the truststores of the SSL parties that you are going to communicate with.