A la hora de trabajar con certificados en Java, usamos el Java Keystore (JKS), que no es más que un almacén de certificados y autoridades de certificación, los cuales se identifican mediante un alias.
Por defecto, la JDK utiliza una trusted keystore, el almacén con los certificados de confianza (CA), en jre/lib/security/cacerts y con la contraseña por defecto changeit.
De esta forma, siempre que estemos trabajando en Java con comunicaciones SSL, cualquier certificado firmado por estas CAs, será un certificado en el que nuestra aplicación confiará y podremos realizar nuestro tripe handshake y realizar una comunicación segura.
Sin embargo, muchas veces vamos a ser nosotros mismos los que crearemos nuestros propios certificados con los que transmitir información de forma segura entre nuestras aplicaciones, sin necesidad de que sea una CA quien nos certifique.
Para ello, Java nos proporciona la herramienta keytool (JAVA_HOME/bin/keytool), la cual nos permite generar nuestros propios certificados y/o importarlos a nuestro trustedStore.
Para poder crear nuestro certificado con la keytool, ejecutaremos el siguiente comando:
$ keytool -genkey -alias my-alias -keyalg RSA -keypass changeit -storepass changeit -keystore keystore.jks
Como vemos, le estamos diciendo que genere una nueva clave (-genkey) con el alias my-alias, utilizando el algoritmo RSA, indicando el password de la key y del store, y diciéndole que queremos almacenarlo en el almacén keystore.jks.
Cuando ejecutamos el comando, nos pedirá una serie de valores (nombre, unidad organizativa, organización, ciudad, etc.). Rellenamos estos valores y finalmente se nos generará nuestro certificado en nuestro almacén.
Ahora ya podemos utilizar nuestro certificado en nuestra aplicación servidor para que haya una comunicación segura.
Sin embargo, cuando un cliente vaya a conectarse a nuestro servidor por SSL, nuestro certificado no estará dentro de su trustedStore, lo cual significa que no confiará en nuestro certificado y que no podrá realizar el tripe handshake para establecer una comunicación segura.
Para esto, debemos exportar nuestra clave pública en un certificado e importarlo en el trustedStore de nuestro cliente (que podría ser el cacerts de java o bien nuestro propio trustedStore). Para ello, vamos a utilizar de nuevo la herramienta keytool de la siguiente manera. Lo primero, exportar nuestra clave pública en un certificado.
$ keytool -export -alias my-alias -storepass changeit -keystore keystore.jks -file my_certificate.cer
Aquí le estamos indicando a la herramienta keytool que queremos exportar el certificado con el alias my-alias, el cual está el en almacen keystore.jks (indicando el password del almacen) y que queremos exportarlo al fichero my_certificate.cer.
Una vez que tenemos nuestro certificado exportado, tan solo nos queda importarlo a nuestro almacén de certificados de confianza, indicando que queremos importar nuestro certificado en el almacén de certificados de confianza.
$ keytool -import -v -trustcacerts -alias my-alias -file my_certificate.cer -keystore cacerts.jks -keypass changeit -storepass changeit
Y ahora sí, si utilizamos este almacén de confianza en nuestro cliente, podremos realizar una comunicación segura entre cliente y servidor.
Finalmente, si deseamos listar los certificados que tenemos en nuestro almacen de confianza y ver sus detalles (como por ejemplo ver cuando caduca nuestro certificado), podemos utilizar el siguiente comando.
$ keytool -list -v -keystore cacerts.jks