java - enabled - tomcat add ssl certificate
Autenticación mutua con Tomcat 7 (4)
Intentaría los siguientes pasos
- Enrolle el contenedor como lo ha configurado en 8443.
- Ejecute su aplicación cliente con -Djavax.net.debug = SSL
Ese comando desplegará PILAS de información. Lo que necesita verificar es que el servidor está presentando una lista de CA que aceptará para la autenticación mutua. Si las CA enumeradas no contienen su certificado, entonces el cliente no tendrá idea de cómo encontrar una coincidencia para el servidor.
Esto se puede hacer mucho más fácil usando el comando openssl ''s_client''
openssl s_client -connect localhost:8443 -showcerts
Eso dará formato a cierta información que puede ser incalculable en su valor de depuración esto.
Si el servidor no presenta una lista de CA "aceptables", tendrá que hacer algo de magia cuando genere su conjunto de certificados.
Déjame saber lo que descubres y con suerte puedo guiarte en la dirección correcta.
OP agregó información adicional
De acuerdo, entonces lo siguiente es un problema para usted:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 263 bytes
---
Dos cosas saltan de inmediato
- El servidor no tiene un certificado de igual
- No hay nombres de CA de clientes enumerados
Entonces para (1):
- asegúrese de que su almacén de claves de hecho tenga el alias ''tomcat'' en él usando keytool.
- las cosas de la contraseña de la tienda / clave en Tomcat son tontas. por razones de cordura, agregue los atributos keystorePassword y keyPassword a su conector con valores idénticos. La documentación para Tomcat 7 indica que keystorePass se establecerá de forma predeterminada en el keyPass si no está configurado. Si su keyPass y keystorePass son los mismos, configure únicamente el atributo keyPass.
Ahora, para (2) realmente necesitamos (1) trabajar primero, así que ponlo en marcha y veremos dónde estamos en ese momento.
Estoy intentando configurar un servicio web Java que se ejecute en Tomcat 7 para usar la autenticación mutua (bidireccional). Parece que no importa lo que haga, conectarse al servicio en el puerto seguro no funciona.
Esto es lo que hice para crear certificados y almacenes de claves, y tal:
//create the key and certificate for the tomcat server.
keytool -genkey -v -alias tomcat -keyalg RSA -validity 3650 -keystore tomcat.keystore
//create the key and certificate for the client machine.
keytool -genkey -v -alias clientkey -keyalg RSA -storetype PKCS12 -keystore client.p12
//export the client key
keytool -export -alias clientkey -keystore client.p12 -storetype PKCS12 -rfc -file client.cer
//import the client key into the server keystore
keytool -import -v -file client.cer -keystore tomcat.keystore
Aquí está el conector en el archivo server.xml:
<Connector port="8443"
maxThreads="150"
scheme="https"
secure="true"
sslProtocol="TLS"
clientAuth="true"
keystoreFile="tomcat.keystore"
keystorePass="tomcat"
truststoreFile="tomcat.keystore"
truststorePass="tomcat"/>
El archivo tomcat-users.xml se ve así:
<tomcat-users>
<role rolename="tomcat"/>
<role rolename="admin"/>
<!-- note that the actual values for CN, OU, O, L, ST are different, but they match the values created in the client certificate -->
<user username="CN=name, OU=unit, O=org, L=locality, ST=state, C=US" password="null" roles="admin" />
</tomcat-users>
Los siguientes están configurados en el inicio:
-Djavax.net.ssl.keyStoreType=jks
-Djavax.net.ssl.keyStore=tomcat.keystore
-Djavax.net.ssl.keyStorePassword=tomcat
-Djavax.net.ssl.trustStore=tomcat.keystore
-Djavax.net.ssl.trustStorePassword=tomcat
-Djavax.net.debug=SSL
Finalmente, copié el archivo client.p12 a mi máquina cliente y lo importé a los certificados de cliente de Firefox.
Primer problema: cuando toco un punto final en mi servicio (ejemplo - https://my.server.com:8443/test ) desde Firefox, recibo la respuesta "Falló la conexión segura". SSL recibió un registro que excedió la longitud máxima permitida. (Código de error: ssl_error_rx_record_too_long)
Segundo problema: realmente no quiero ejecutar este conector en el puerto 8443. Quiero ejecutarlo en el puerto 7800 (que es nuestro estándar de la compañía para HTTPS). Cuando cambio el puerto en el Connector a 7800 e intento llegar al punto final (ejemplo - https://my.server.com:7800/test ), entonces nunca resuelve la página.
Entonces, en algún lugar, obviamente me falta una pieza crucial. ¿Alguien puede ver mi error?
ACTUALIZACIÓN: después de los comentarios de @Dave G
Ejecutando el comando:
openssl s_client -connect localhost:8443 -showcerts
produce el siguiente resultado:
CONNECTED(00000003)
140642290976584:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:766:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 263 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
También agregué -Djavax.net.debug = SSL al inicio. Esto genera lo siguiente al comienzo del archivo catalina.out:
trustStore is: tomcat.keystore
trustStore type is : jks
trustStore provider is :
init truststore
adding as trusted cert:
Subject: CN=localhost, OU=unit, O=org, L=Springfield, ST=MO, C=US
Issuer: CN=localhost, OU=unit, O=org, L=Springfield, ST=MO, C=US
Algorithm: RSA; Serial number: 0x5485b5a5
Valid from Mon Dec 08 14:28:53 UTC 2014 until Thu Dec 05 14:28:53 UTC 2024
adding as trusted cert:
Subject: CN=William Jackson, OU=unit, O=org, L=Springfield, ST=MO, C=US
Issuer: CN=William Jackson, OU=unit, O=org, L=Springfield, ST=MO, C=US
Algorithm: RSA; Serial number: 0x5485b6af
Valid from Mon Dec 08 14:33:19 UTC 2014 until Sun Mar 08 14:33:19 UTC 2015
trigger seeding of SecureRandom
done seeding SecureRandom
Y luego MUCHO de:
Ignoring unavailable cipher suite: <suite name>
Ignoring unsupported cipher suite: <suite name>
Ok, después de excavar mucho más, finalmente conseguí que funcionara. Muchas gracias a @Dave G y este tutorial: http://java-notes.com/index.php/two-way-ssl-on-tomcat de la cual se parafrasean la mayoría de estas instrucciones.
En general, los pasos para obtener la autenticación mutua funcional son los siguientes:
- Crea un certificado para el servidor Tomcat. El cliente tiene que confiar en este certificado.
- Cree un almacén de claves para el servidor tomcat e importe el certificado del servidor en él.
- Crea un certificado para el cliente. El servidor tiene que confiar en este certificado.
- Importe el certificado del cliente en el almacén de claves del servidor
- Actualice el archivo tomcat server.xml con el XML de Connector correcto.
Los pasos anteriores son necesarios en el servidor. Una vez completado, para configurar el cliente, haga lo siguiente:
- Copie el certificado del cliente del servidor al cliente.
- Use el certificado del cliente cuando se comunique con el servidor (este proceso varía según la naturaleza de la aplicación del cliente).
Para la configuración del certificado, ejecuté lo siguiente en la máquina del servidor:
# For the following commands, set the values in parenthesis to be whatever makes sense for your environment. The parenthesis are not necessary for the command.
# This is an all-in-one command that generates a certificate for the server and places it in a keystore file, while setting both the certifcate password and the keystore password.
# The net result is a file called "tomcat.keystore".
keytool -genkeypair -alias (serveralias) -keyalg RSA -dname "CN=(server-fqdn),OU=(organizationalunit),O=(organization),L=(locality),ST=(state),C=(country)" -keystore tomcat.keystore -keypass (password) -storepass (password)
# This is the all-in-one command that generates the certificate for the client and places it in a keystore file, while setting both the certificate password and the keystore password.
# The net result is a file called "client.keystore"
keytool -genkeypair -alias (clientalias) -keyalg RSA -dname "CN=(client),OU=(organizationalunit),O=(organization),L=(locality),ST=(state),C=(country)" -keypass (password) -keystore client.keystore -storepass (password)
# This command exports the client certificate.
# The net result is a file called "client.cer" in your home directory.
keytool -exportcert -rfc -alias (clientalias) -file client.cer -keypass (password) -keystore client.keystore -storepass (password)
# This command imports the client certificate into the "tomcat.keystore" file.
keytool -importcert -alias (clientalias) -file client.cer -keystore tomcat.keystore -storepass (password) -noprompt
Los certificados ahora deben configurarse adecuadamente. El siguiente paso es configurar su conector en el servidor tomcat.xml. Agregue un elemento conector que se vea así:
<Connector port="8443"
maxThreads="150"
scheme="https"
secure="true"
SSLEnabled="true"
truststoreFile="/full/path/to/tomcat.keystore"
truststorePass="(password)"
keystoreFile="/full/path/to/tomcat.keystore"
keystorePass="(password)"
clientAuth="true"
keyAlias="serverkey"
sslProtocol="TLS"/>
Tenga en cuenta que en el XML anterior:
- El atributo "puerto" puede ser lo que quieras.
- Los atributos "keystoreFile" y "truststoreFile" deben ser rutas completas. Tomcat no se ve en el mismo directorio que server.xml de forma predeterminada.
- Los atributos "keystorePass" y "truststorePass" deben coincidir con el valor (contraseña) que utilizó en la creación del archivo tomcat.keystore.
- El atributo "clientAuth" debe establecerse en "verdadero". Esto es lo que desencadena la autenticación mutua.
Además, en server.xml, asegúrese de que NO tenga definido AprLifecycleListner. El XML para ese oyente se verá algo así:
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
Ese elemento debe ser eliminado / comentado. AprLifecycleListener no se configura de la misma manera que se describe arriba, y no funcionará con estas instrucciones.
Reinicia Tomcat. La configuración del servidor debe estar completa.
Probé mi trabajo usando Firefox, porque es fácil agregarle certificados de cliente. Abre Firefox y trata de conectarte a un punto final de tu servicio Tomcat en el puerto definido en tu conector.
Ex: https://mytomcatdomain.com:8443/test
Cuando hagas esto, deberías recibir la alerta estándar de Firefox sobre una conexión que no es de confianza porque creamos un certificado autofirmado para nuestro servidor Tomcat. Agregue una excepción para el certificado para que nuestro cliente (Firefox) confíe en nuestro servidor (Tomcat).
Una vez que haya agregado la excepción, debería recibir un mensaje de "Falló la conexión segura". El código de error es "ssl_error_bad_cert_alert". Esto confirma que nuestro servidor Tomcat está solicitando la autenticación del cliente. La solicitud está fallando porque aún no hemos configurado Firefox para enviar nuestro certificado de cliente de confianza.
Para configurar Firefox, necesitamos hacer un poco más de magia:
// Create a file called DumpPrivateKey.java. The contents should look like so:
public class DumpPrivateKey {
public static void main(String[] args) throws Exception {
final String keystoreName = args[0];
final String keystorePassword = args[1];
final String alias = args[2];
java.security.KeyStore ks = java.security.KeyStore.getInstance("jks");
ks.load(new java.io.FileInputStream(keystoreName), keystorePassword.toCharArray());
System.out.println("-----BEGIN PRIVATE KEY-----");
System.out.println(new sun.misc.BASE64Encoder().encode(ks.getKey(alias, keystorePassword.toCharArray()).getEncoded()));
System.out.println("-----END PRIVATE KEY-----");
}
}
Compila el archivo java con el siguiente comando:
javac DumpPrivateKey.java
Ahora vamos a usar esta pequeña utilidad para extraer una clave del archivo client.keystore que creamos más arriba. Copie los archivos client.keystore y client.cer en el mismo directorio que su clase DumpPrivateKey. Ejecuta lo siguiente:
# This extracts the client key from the client keystore
java DumpPrivateKey client.keystore (password) clientkey > clientkey.pkcs8
# This creates a client.p12 file that can be used by Firefox
openssl pkcs12 -export -in client.cer -inkey clientkey.pkcs8 -password pass:(password) -out client.p12
Tenga en cuenta que en el código anterior, (contraseña) debe ser la contraseña que utilizó para crear el cliente.keystore.
Abre las preferencias de Firefox. Haga clic en la pestaña "Certificados". Haga clic en el botón "Ver certificados". Haga clic en la pestaña "Sus certificados".
Haga clic en el botón "Importar" y busque el archivo "client.p12" que se creó anteriormente. Debería pedírsele que ingrese la contraseña para el certificado del cliente.
Suponiendo que el "cliente.p12" se importó con éxito, ahora puede actualizar su página de Firefox, y debe obtener una respuesta exitosa desde su punto final del servidor Tomcat.
@wbj, la exportación de PrivateKeyEntry de JKS a PKCS # 12 se puede hacer mucho más fácil:
keytool -importkeystore -srckeystore client.keystore -destkeystore client.p12 -deststoretype PKCS12 -srcalias client -deststorepass <password> -destkeypass <password>
Aclamaciones.
Me tomó algo de tiempo hacerlo funcionar correctamente usando certificados Openssl, redactando mis notas para que pueda ayudar a otros a visitar esta página.
Paso 1: crea tu propia raíz CA
~/openssl$ mkdir -m 0700 /home/ubuntu/openssl/CA /home/ubuntu/openssl/CA/certs /home/ubuntu/openssl/CA/crl /home/ubuntu/openssl/CA/newcerts /home/ubuntu/openssl/CA/private
~/openssl$ touch /home/ubuntu/openssl/CA/indext.txt
~/openssl$ echo 1000 >> /home/ubuntu/openssl/CA/serial
~/openssl$ mv karun-tomcat-root-ca.key CA/private/
~/openssl$ sudo vi /etc/openssl.cnf
# Make changes here
dir = /home/ubuntu/openssl/CA
#optionally change policy definitions as well
~/openssl$ openssl genrsa -des3 -out karun-tomcat-root-ca.key 2048
#In below command make sure to use CN=<hostname of your machine>
~/openssl$ openssl req -new -x509 -days 36520 -key karun-tomcat-root-ca.key -out karun-tomcat-root-ca.crt -config openssl.cnf
~$ sudo cp ~/openssl/CA/certs/karun-tomcat-root-ca.crt /usr/share/ca-certificates/
# make sure in the UI you enable/select the certificate created above
~$ sudo dpkg-reconfigure ca-certificates
# Now reboot ubuntu machine just to make sure certificates are loaded successfully and tomcat picks it
Paso 2: crea el par de claves del servidor Tomcat
~$ openssl genrsa -out tomcat-server.key 2048
# Use common name = <Give IP address>, department = Tomcat Server CSR
~$ openssl req -new -sha256 -config ~/openssl/openssl.cnf -key tomcat-server.key -out tomcat-server.csr
~$ openssl x509 -req -sha256 -days 36520 -in tomcat-server.csr -signkey tomcat-server.key -CA ~/openssl/CA/certs/karun-tomcat-root-ca.crt -CAkey ~/openssl/CA/private/karun-tomcat-root-ca.key -CAcreateserial -out tomcat-server.crt
~$ openssl pkcs12 -export -name karun-tomcat-server-cert -in tomcat-server.crt -out tomcat-server.p12 -inkey tomcat-server.key -CAfile ~/openssl/CA/certs/karun-tomcat-root-ca.crt -caname karun-root -chain
~$ keytool -importkeystore -destkeystore tomcat-server.jks -srckeystore tomcat-server.p12 -srcstoretype pkcs12 -alias karun-tomcat-server-cert
~$ keytool -import -alias karun-root -keystore tomcat-server.jks -trustcacerts -file ~/openssl/CA/certs/karun-tomcat-root-ca.crt
# **(LATER)** Run this once client cert is generated
~$ keytool -importkeystore -alias karun-tomcat-client-cert -srckeystore ~/client-certs/tomcat-client.p12 -srcstoretype PKCS12 -destkeystore tomcat-server.jks -deststoretype JKS
# **(LATER)** Run this once tomcat server started successfully
~$ openssl s_client -connect localhost:8443 -cert ~/client-certs/tomcat-client.crt -key ~/client-certs/tomcat-client.key -debug -showcerts
Paso 3: Crear par de claves del lado del cliente
~$ openssl genrsa -out tomcat-client.key 2048
# Use common name = <tomcat-user.xml''s user say ''admin''>, department = Tomcat Client CSR
~$ openssl req -new -sha256 -config ~/openssl/openssl.cnf -key tomcat-client.key -out tomcat-client.csr
~$ openssl x509 -req -sha256 -days 36520 -in tomcat-client.csr -signkey tomcat-client.key -CA ~/openssl/CA/certs/karun-tomcat-root-ca.crt -CAkey ~/openssl/CA/private/karun-tomcat-root-ca.key -CAcreateserial -out tomcat-client.crt
~$ openssl pkcs12 -export -name karun-tomcat-client-cert -in tomcat-client.crt -out tomcat-client.p12 -inkey tomcat-client.key -CAfile ~/openssl/CA/certs/karun-tomcat-root-ca.crt -caname karun-root -chain
~$ (optional step) keytool -importkeystore -destkeystore tomcat-client.jks -srckeystore tomcat-client.p12 -srcstoretype pkcs12 -alias karun-tomcat-client-cert
~$ (optional step) keytool -import -alias root -keystore tomcat-client.jks -trustcacerts -file ~/openssl/CA/certs/karun-tomcat-root-ca.crt
Paso 4: Cambios de Tomcat
# Make this change in server.xml of tomcat server
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="/opt/tomcat/openssl-certs/tomcat-server.jks"
keystorePass="password"
keyAlias="karun-tomcat-server-cert"
truststoreFile="/opt/tomcat/openssl-certs/tomcat-server.jks"
truststorePass="password"
clientAuth="true" sslProtocol="TLS" />
Paso 5: reinicia el servidor Tomcat y comprueba los registros para asegurarte de que no haya errores en el arranque
Paso 6: Cargar cert de cliente en el navegador
En su navegador, p. Ej .: firefox, navegue en Preferencias -> Avanzado -> Certificado -> Ver certificados -> Sus certificados
Importar "tomcat-client.p12"
https://<tomcat ip>:8443/
Referencias
http://pages.cs.wisc.edu/~zmiller/ca-howto/
http://www.area536.com/projects/be-your-own-certificate-authority-with-openssl/