Cause
This error might be caused of certain things such as, the keystoretype is not defined in server.xml thus the JSSE could not recognized the keystore as the keystore is not on default type which is JKS. Other thing is the certificate has not be imported to keystore that is generated by keytool as it does not let you import an existing private key for which you already have a certificate.
Resolution
Import private key and certificate into Java Key Store (JKS)
Apache Tomcat and many other Java applications expect to retrieve SSL/TLS certificates from a Java Key Store (JKS). Jave Virtual Machines usually come with keytool to help you create a new key store.
Keytool helps you to:
- create a new JKS with a new private key
- generate a Certificate Signung Request (CSR) for the private key in this JKS
- import a certificate that you received for this CSR into your JKS
Keytool does not let you import an existing private key for which you already have a certificate. So you need to do this yourself, here’s how:
Let’s assume you have a private key (key.pem) and a certificate (cert.pem), both in PEM format as the file names suggest.
PEM format is ‘kind-of-human-readable’ and looks like e.g.
-----BEGIN CERTIFICATE----- Ulv6GtdFbjzLeqlkelqwewlq822OrEPdH+zxKUkKGX/eN . . (snip) . 9801asds3BCfu52dm7JHzPAOqWKaEwIgymlk= ----END CERTIFICATE-----
Convert both, the key and the certificate into DER format using openssl :
openssl pkcs8 -topk8 -nocrypt -in key.pem -inform PEM -out key.der -outform DER openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER
Now comes the tricky bit, you need something to import these files into the JKS. ImportKey will do this for you, get the ImportKey.java (text/x-java-source, 6.6 kB, info) source or the compiled (Java 1.5 !) ImportKey.class (application/octet-stream, 3.3 kB,info) and run it like[gview file=”http://rmohan.com/wp-content/uploads/2014/05/ImportKey.zip”]
user@host:~$ java ImportKey key.der cert.der Using keystore-file : /home/user/keystore.ImportKey One certificate, no chain. Key and certificate stored. Alias:importkey Password:importkey
Now we have a proper JKS containing our private key and certificate in a file called keystore.ImportKey, using ‘importkey’ as alias and also as password. For any further changes, like changing the password we can use keytool.
- Convert your private key and certificate from the PEM format into DER (PKCS8, not PKCS12):
- Modify the
ImportKey.java
to set a passphrase for the keystore and an alias to access your certificate. - Compile it into a class file:
- Run it to import your key and certificate:
The application then creates a file keystore.ImportKey
which holds a combination of your certificate and private key that you can put into your application directory, e.g. underconf/keystore
.
You do not need to add any intermediate certificate authorities to the keystore.
Set up your server.xml
You are now ready to use your certificate. Modify your server.xml inside the application directory and add a Connector
entry like this:
- Providing the
keystoreFile
andkeystorePass
(the password you chose above) tells the application how to access the keystore.
If you encountered the “java.io.IOException: jsse.invalid_ssl_conf
” exception before, this is most likely the answer to it. - Setting the
keyAlias
(you put it into theImportKey.java
) hints which key to use.
If you got an exception like “java.io.IOException: Alias name foobar does not identify a key entry
” you were providing an existing name but only a certificate without a private key. - You can also modify those settings later by using the corresponding
keytool
commands.
Now you should be able to restart your application and access it via SSL on port 8443. If it does not come up (maybe only listening on non-SSL ports) check the logs for any of the above exceptions.
Important: Remove any world and group permissions on the server.xml to keep your passphrase hidden from other users/applications on the server. You may want to chmod your keystore, too.
Recent Comments