close

Mis proyectos

15 de de diciembre de, el año 2015
Decidí hacer un prototipo de, por lo que he investigado cómo hacer la autenticación de clientes TLS con un servidor del lado de Java / primavera (se puede leer en incluso si no eres un desarrollador de Java - la mayor parte del mensaje es java-agnóstico) . ¿Por TLS autenticación de cliente? Porque esa es la forma más estándar para autenticar a un usuario que posee un certificado (en una tarjeta inteligente, por ejemplo). Por supuesto, los certificados de tarjetas inteligentes no son la única aplicación - las organizaciones pueden emitir certificados internos a los usuarios que almacenan en sus máquinas. El punto es tener un mecanismo de autenticación que es más seguro que un simple par nombre de usuario / contraseña. Es un problema de usabilidad, especialmente con tarjetas inteligentes, pero que está más allá del alcance de este post. Así pues, con TLS clientAuth, además de la identidad del servidor ser verificado por el cliente (mediante el certificado de servidor), la identidad del cliente también es verificado por el servidor. Esto significa que el cliente tiene un certificado emitido por una autoridad, que confía en el servidor de forma explícita.En términos generales, el cliente tiene que firmar digitalmente un desafío con el fin de demostrar que posee la clave privada que corresponde al certificado que presenta. (Este proceso también se puede encontrar bajo) Hay dos formas de acercarse a eso. La primera, y más intuitiva, es comprobar cómo configurar Tomcat (o su contenedor de servlets). El da la configuración de Tomcat en la parte inferior. El "almacén de claves" es la tienda donde se almacena el certificado del servidor (+ clave privada), y "trustStore" es el almacén que contiene el certificado raíz de la autoridad que se utiliza para firmar los certificados de cliente. Sin embargo, esa configuración es aplicable sólo si tiene una sola instancia del contenedor de servlets expuesto a sus usuarios. Lo más probable en la producción, sin embargo, usted tiene un número de casos / nodos que ejecutan la aplicación, detrás de un equilibrador de carga, y en el equilibrador de carga, que luego envía las solicitudes descifrado al contenedor de servlets través de una conexión HTTP plano. En ese caso, las opciones son o noTLS terminar en el equilibrador de carga, que es lo más probable es que no es una buena idea, o que tiene que remitir el certificado de cliente de alguna manera de su equilibrador de carga a su nodo. Voy a usar nginx como un ejemplo. La generación de los pares de claves, certificados, solicitudes de firma de certificados, certificados y almacenes de claves firmadas vale la pena un post aparte. . Es necesario openssl y herramienta de claves / y un grupo de comandos. Para la producción, por supuesto, es aún más complicada, ya que para el certificado de servidor que había necesidad de enviar un CSR a una CA. Una vez hecho esto, en la configuración de nginx, usted debe tener algo como: servidor {    escuchar ssl 443;    yourdomain.com server;    server.cer ssl_certificate;    # Esa es la clave privada    server.key ssl_certificate_key;    # Que cuenta con el certificado de la CA que firmó los certificados de cliente en los que confía. = TrustStore en Tomcat    ca.pem ssl_client_certificate;    # Esto indica si se requiere la autenticación del cliente, u opcional (clientAuth = "true" vs"Quiero" en Tomcat)    ssl_verify_client en;    ubicación / {       # Configuración PROXY_PASS aquí, inclding X-reenviado-Para cabeceras. Nota: tener un cuidado especial para no reenviar X-Cliente-Certificado cabeceras forjado       proxy_set_header X-Cliente-Certificado $ ssl_client_cert;    } }  De esa manera el certificado de cliente se enviará como una cabecera (). Esto parece un truco, y probablemente lo es, ya que el certificado de cliente no es exactamente una pequeña cadena. Pero esa es la única manera que se me ocurre. . Hay un pequeño problema con eso, sin embargo (y es lo mismo para la solución Tomcat también) - si se habilita la autenticación del cliente para todo el dominio, no se puede tener páginas totalmente desprotegidos. Incluso si la autenticación es opcional ( "querer"), el diálogo del navegador (desde la cual el usuario selecciona un certificado) todavía se activaría sin importar las páginas que el usuario abre por primera vez. Lo bueno es que un usuario sin certificado todavía sería capaz de navegar por páginas que no están protegidos de forma explícitacon el código. Pero para una persona que tiene un certificado, la apertura de la página principal se abra el diálogo, a pesar de que no puede ser que desee para autenticar. Hay algo que se pueda hacer para manejarlo. De hecho, he visto hacer con Perl "por página", pero no estoy seguro de que esto se puede hacer con una configuración de Java. Bueno, puede, si no utilizar un contenedor de servlets, pero manejar sus apretones de manos TLS mismo. Pero eso no es deseable. Normalmente, se necesitaría el diálogo sólo para una única URL de autenticación navegador. "/ Login", o como en mi caso con el "/ autenticar" punto final (el usuario se redirige al proveedor de identidad / autenticación URL, donde normalmente tendría que introducir nombre de usuario / contraseña, pero en este caso se tendría que acaba de seleccionar el certificado propiamente dicho). Lo que se puede hacer es tener acceso a ese determinado punto final de un subdominio. Eso significaría tener otra sección de "servidor" en la configuración de nginx con el subodmain y la ssl_verify_client en adelante, mientras que el dominio ordinario permanece sin ningún tipo de clientela verificación del certificado. De esta manera, será autenticada sólo peticiones al subdominio. Ahora, cómo hacer la autenticación real. La implementación de OpenID Conectar mencionado anteriormente utiliza la seguridad de la primavera, pero puede ser cualquier cosa. apoya los dos casos mencionados anteriormente (Tomcat y nginx Tomcat). Eso hace que la aplicación equilibrador de carga-consciente, pero puede elegir con seguridad uno u otro enfoque y deshacerse de la otra mitad a partir del código. Para el enfoque Tomcat única, el X509Certificate se obtiene simplemente por estas líneas:     certs X509Certificate [] = ([] X509Certificate) solicitud        .getAttribute ( "javax.servlet.request.X509Certificate");     // Comprobar si no está vacío y obtener la primera  Para el enfoque nginx-en-delantero, que es un poco más complicado. Tenemos que conseguir la cabecera, transformarlo a un estado adecuado y luego analizarlo. (Tenga en cuenta que no estoy usando el filtro de seguridad X509-primavera, ya que sólo es compatible con el enfoque de un solo gato.) Cadena certificateHeader =request.getHeader ( "X-Cliente-Certificado"); si (certificateHeader == null) {     response.sendError (HttpServletResponse.SC_UNAUTHORIZED);     regreso; } // El equilibrador de carga (por ejemplo nginx) reenvía el certificado // En una cabecera mediante la sustitución de nuevas líneas con espacios en blanco // (2 o más). sustituir también las pestañas, que a veces nginx // Puede enviar en lugar de espacios en blanco Cadena del certificado, = certificateHeader      .ReplaceAll ( "\\ s {2,}", System.lineSeparator ())      .ReplaceAll ( "\\ t ", System.lineSeparator ()); userCertificate = (X509Certificate) CertificateFactory     .generateCertificate (nueva ByteArrayInputStream (         certificateContent.getBytes ( "ISO-8859-11")));  El "hackiness" Ahora es obvio, porque la forma en nginx envía el certiciate codificado-PEM, pero en una línea. Afortunadamente, las líneas están separadas por algún tipo de espacios en blanco (una vez fue espacios, otra vez fue pestañas (en una máquina Windows)), por lo que puede volver a su formato original PEM (incluso sinnecesariamente a sabiendas de que una línea de PEM es de 64 caracteres). Puede ser que otras versiones de nginx u otros servidores no poner espacios en blanco, por lo que la división en líneas de 64 caracteres puede tener que ser hecho. Luego usamos una fábrica de certificados X.509 para crear un objeto certificado. Eso es básicamente la misma. Entonces podemos usar para extraer el CN ​​(nombre común), o cualquier otro campo de la identificación exclusiva, a partir del certificado, y lo utilizan para cargar el correspondiente registro de usuario de base de datos. Eso es todo, o al menos lo que tengo de mi prueba de concepto. Es un caso de uso nicho, y, pero para los sistemas de correo de identificación segura nacionales, para la banca electrónica y para aplicaciones internas que probablemente no es una mala idea. Archivado bajo: por Bozho
Deja una Respuesta

Previous Post     Next Post


TAGS


CATEGORIES

.