In particular, we'll focus on overcoming the following two
shortcomings:
The following example uses a real SSL certificate chain from a real certificate authority and was done in the context of the Java Advanced Management Console 2.1 application. Java AMC is a Java EE application and requires Oracle's WebLogic application server to function. In this instance we'll be updating a keystore associated with WebLogic, but in reality this Java keystore should be no different from any other Java keystore, so these steps should apply elsewhere just fine.
We'll leave the minutiae of applying for a trusted certificate as an exercise for the reader; one of the first steps towards getting a certificate involves creating and submitting a CSR (Certificate Signing Request) to a Certificate Authority. A byproduct of this process is that a private key file is generated based on the information in the CSR. This file, when opened, looks something like this:
-----BEGIN PRIVATE KEY-----
encryptedgobbledygook line 1
...
encryptedgobbledygook line n
-----END PRIVATE KEY-----
This private key file is in PEM (Privacy Enhanced Mail) format, and will take a .pem suffix. For our example, the file is stored as:
For this article, we used Comodo (one of many alternatives) as our Certificate Authority. When the entire process with Comodo was complete, the following documents were ultimately received from them:
With these files in place we can now begin the importing
process. We will take advantage of enhancements added to keytool
with the Java 6 release: namely that keytool can merge
and import keystores that are in PKCS12 format.
With this new information what remains is to figure out how to
convert our private key and certificate chain into a PKCS12
file. For this functionality we resort to the capabilities
found in the ubiquitous OpenSSL
toolkit, available on virtually all popular compute
platforms. In the example that follows, we'll be running on
a Windows system and will utilize the Cygwin environment to run the
required OpenSSL commands.
Step 1. (From Cygwin) Concatenate the certificates comprising the CA-supplied root certificate chain to one file. Include only the root certificate and intermediate certificate(s) and exclude the host-specific SSL certificate.
$ cat AddTrustExternalCARoot.crt COMODORSAAddTrustCA.crt COMODORSADomainValidationSecureServerCA.crt > BUNDLE.crt
Step 2. (From Cygwin) Create a PKCS12 keystore. This
command incorporates both the certificate chain along with the SSL
private key and certificates. Your passwords may vary.
$ openssl pkcs12 -export -chain -in amc-server_jtconnors_com.crt -inkey private-key.pem -out keystore.p12 -name amc-server -CAfile BUNDLE.crt
Enter Export Password: changeit
Verifying - Enter Export Password: changeit
Step 3. (From Windows CMD) Using keytool, import the
PKCS12 keystore into the resulting JKS keystore called keystore.jks.
Again, you may select different passwords.
> "c:\Program Files\Java\jdk1.8.0_66\bin\keytool.exe" -importkeystore -destkeystore keystore.jks -srckeystore keystore.p12 -alias amc-server
Enter destination keystore password: changeit
Re-enter new password: changeit
Enter source keystore password: changeit
Step 4. With the keystore successfully created we can now take the optional step of further verifying it. Certain Java-based application frameworks, like Oracle's WebLogic for example, can be finicky about the completeness and order of the certificate chain. To help validate the keystore, we can use the ValidateCertChain program which comes bundled with WebLogic 12c and can be found in the distribution's weblogic.jar file. Here's a sample invocation of the program on our recently created keystore.jks file:
> java -cp %MW_HOME%\wlserver\server\lib\weblogic.jar utils.ValidateCertChain -jks amc-server keystore.jks
Cert[0]: CN=amc-server.jtconnors.com,OU=PositiveSSL,OU=Domain Control Validated
Cert[1]: CN=COMODO RSA Domain Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
Cert[2]: CN=COMODO RSA Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
Cert[3]: CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust AB,C=SE
Certificate chain appears valid
Here's hoping these examples save you some time, and more
importantly, a little grief.
Postscript
After having received recommendations from the engineers far better versed in AMC and WebLogic, the following section was added to briefly discuss alternatives to the above mentioned OpenSSL solution.
Alternative A: For people that have complete control of the certificate generating process, they can, as previously hinted, use keytool exclusively for this process. For the first phase of the process they can use keytool in the following general manner (arguments to keytool will vary) to generate a keypair and certificate request:
keytool -keystore keystore.jks -genkeypair -keyalg rsa
keytool -keystore keystore.jks -certreq
In this scenario, OpenSSL would not be required since the keypair is already stored in the keystore. From here you can import the certificates following a form similar to this:
keytool -import -keystore keystore.jks -alias root -file AddTrustExternalCARoot.crt
keytool -import -keystore keystore.jks -alias intermediate1 -file COMODORSAAddTrustCA.crt
keytool -import -keystore keystore.jks -alias intermediate2 -file COMODORSADomainValidationSecureServerCA.crt
keytool -import -keystore keystore.jks -alias mykey -file amc-server_jtconnors_com.crt
In the last command, "-alias mykey" is essential and must match the key pair in the keystone. As a shortcut, you could also concatenate all PEM-encoded certificates into a big file and then call:
keytool -import -keystore keystore.jks -alias mykey -file thebigfile
Alternative B: Along with the ValidateChain program WebLogic 12c's weblogic.jar file also includes a utility called ImportPrivateKey which can also used to import a certificate chain into a Java keystore. This utility command is described in Creating a Keystore Using ImportPrivateKey subsection of WebLogic documention on Configuring Keystores. The command follows a form like this:
java -cp %WL_HOME%\server\lib\weblogic.jar utils.ImportPrivateKey -keystore newkeystore -storepass **keystorepassword** -alias amctrust -certfile certificate.pem -keyfile privatekey.pem [-keyfilepass **privatekeypassword**]
For further edification please consult the WebLogic docs.