2010-05-10 15 views
8

Hay un debate en curso en el security and trust working group for NHIN Directregarding the IP-to-domain mapping problem that is created with traditional SSL. Si un HISP (según lo define NHIN Direct) desea alojar miles de "Dominios de salud" NHIN Direct para proveedores, entonces tendrá un "costo inflado artificialmente" tener que comprar una IP para cada uno de esos dominios.TLS con SNI en clientes Java

Debido a que Apache y OpenSSL han publicado recientemente TLS con soporte para la extensión SNI, es posible utilizar SNI como una solución a este problema en el lado del servidor. Sin embargo, si decidimos que vamos a permitir implementaciones del servidor de la capa de transporte NHINDirect para admitir TLS + SNI, entonces debemos requerir que todos los clientes admitan también SNI. Los clientes basados ​​en OpenSSL deberían hacer esto de forma predeterminada y uno siempre podría usar Stunnel para implementar un cliente TLS + SNI con proxy si su implementación de lenguaje de programación SSL no es compatible con SNI. Parece que las aplicaciones Java nativas que usan OpenJDK aún no son compatibles con SNI, pero no puedo obtener una respuesta directa de ese proyecto. Sé que hay bibliotecas OpenSSL Java disponibles, pero no tengo idea de si eso se consideraría viable.

¿Puede darme un resumen "de última generación" de dónde está el soporte TLS + SNI para clientes Java? Necesito una perspectiva de los implementadores de Java sobre esto.

Respuesta

3

Estoy trabajando en el mismo proyecto que ftrotter.

en cuenta el requisito de apoyo a miles de dominios. No creo que las SANs vayan a cortar la mostaza por dos razones. Primero, el tamaño del certificado va a ser enorme, lo que probablemente ocasione problemas de rendimiento como mínimo. En segundo lugar, estos dominios van y vienen con frecuencia, especialmente en los primeros días de NHIN Direct. La carga operativa de tener que actualizar el certificado cada vez que un dominio entra o sale, va a ser inaceptable, en mi humilde opinión.

A petición de ftrotter, busqué en Google el tema de java, TLS y SNI, y otras formas de implementar lo que equivale a una situación de alojamiento virtual con nombre, con un certificado por host virtual. Aquí es lo que he llegado con:

  • JSSE (Java Secure Socket Extension) es compatible con TLS, y tiene "el apoyo parcial" para TLS + SNI. No tengo idea de qué significa el apoyo parcial en este contexto. El comentario que estoy viendo indica que el soporte que existe no es adecuado para hacer hosts virtuales basados ​​en nombres, que es básicamente lo que necesitamos.

  • He encontrado un artículo que afirma la versión JDK7 de JSSE se TLS apoyo + SNI (de fecha 11/20/2008), y he encontrado uno que afirma que no será (fecha 2/27/2009). Ninguno es particularmente autoritario.

  • Algunas de las personas que trabajan en OpenJDK 7 discutieron los problemas relacionados con la adición de soporte de SNI a JSSE en febrero-marzo de 2009, incluida la publicación de un parche de origen. (el hilo comienza aquí: http://www.mail-archive.com/[email protected]/msg00612.html). OpenJDK7 no se lanzará antes de septiembre de 2010. No tengo idea de cuándo se lanzará la plataforma Java 7.

  • No hay nada sustantivo en java.sun.com en absoluto, así que realmente no sé cuáles son los planes de Sun en absoluto.

  • Aparentemente hay una manera diferente de lograr hosts virtuales basados ​​en nombres que aparentemente es ampliamente compatible, utilizando un solo certificado por servidor de alojamiento que contiene múltiples nombres comunes y múltiples nombres de tema.Ver http://wiki.cacert.org/VhostTaskForce y Serve different certs for same Tomcat application via connectors?

Este enfoque sería crear extensas certificados (debido a todas esas SNC y SAN) si usted tiene un montón de máquinas virtuales. Una de las personas en la reciente reunión cara a cara de NHIN Direct hablaba de querer admitir miles de hosts virtuales. Supongo que esto romperá muchas implementaciones. Además, tener que actualizar el certificado cada vez que agrega o elimina un host virtual suena como una carga operacional ridícula.

En resumen, el estado actual de Java para el alojamiento virtual basado en nombre con certificados separados por host virtual parece ser "no se puede". Además, no está claro cuándo o si se agregará.

¿Alguien está de acuerdo o en desacuerdo? ¿Alguien sabe si el proyecto OpenJDK tiene alguna intención de "respaldar" el soporte de SNI para Java 6?

8

JavaSE 7 tiene compatibilidad con SNI en JSSE.

http://docs.oracle.com/javase/7/docs/technotes/guides/security/enhancements-7.html

nota, parece que hay un problema con él, como se puede leer aquí:

SSL handshake alert: unrecognized_name error since upgrade to Java 1.7.0

+1

Y si tiene problemas con la alerta unrecognized_name desde el servidor (que no puede ser ignorado en Clientes JSSE, ver http://bugs.sun.com/ bugdatabase/view_bug.do? bug_id = 7127374) puede desactivar el envío de SNI: jsse.enableSNIExtension = false – eckes

+0

¿Alguna idea de cómo desactivar esto para los applets? – ivb

+0

Puede agregar propiedades de sistema (globales) para Applets y WebStart en el Panel de control del sistema. El archivo JNLP no puede especificar los parámetros del sistema que no están en una lista blanca segura. (Creo que esa lista se puede modificar en alguna parte pero eso no es una interfaz oficial). – eckes

6

también es posible parchear con algunas líneas del orig JDK de Sun (bootclasspath) para que Server Server SNI funcione.

Clase: sun.security.ssl.ServerHandshaker

Añadir campo

/** Use for SNI */ 
    private ServerNameExtension serverNameExtension = null; 

Patch Método ClientHello (añadir estas líneas)

/* Use for SNI */ 
    this.serverNameExtension = (ServerNameExtension)mesg.extensions.get(ExtensionType.EXT_SERVER_NAME); 

Patch Método setupPrivateKeyAndChain (modificar)

if (this.conn != null) { alias = km.chooseServerAlias(algorithm  , null, this.conn); 
    } else     { alias = km.chooseEngineServerAlias(algorithm, null, this.engine); } 

to 

    final Principal[] principals = (this.serverNameExtension == null) ? null : this.serverNameExtension.getHostnamePrincipals(); 
    if (this.conn != null) { alias = km.chooseServerAlias(algorithm  , principals, this.conn); 
    } else     { alias = km.chooseEngineServerAlias(algorithm, principals, this.engine); } 

Añadir a la Clase sun.security.ssl.ServerNameExtension

static final class ServerNamePrincipal implements Principal { 
    private final String name; 
    ServerNamePrincipal(final String name) { this.name = name; } 
    @Override public String getName() { return this.name; } 
    @Override public String toString() { return this.name; } 
} 

public Principal[] getHostnamePrincipals() { 
    final List<Principal> principals = new LinkedList<>(); 
    for(final ServerName name : this.names) { 
     if(name.type == NAME_HOST_NAME) { principals.add(new ServerNamePrincipal(name.hostname)); } 
    } 
    return principals.toArray(new Principal[principals.size()]); 
}