java - Inicialización SSLContext
security jsse (2)
Estoy mirando la guía de referencia JSSE
, necesito obtener una instancia de SSLContext
para crear un SSLEngine
, así que puedo usarlo con Netty
para habilitar la seguridad.
Para obtener una instancia de SSLContext
, utilizo SSLContext.getInstance()
. Veo que el método se reemplaza varias veces, por lo que puedo elegir el protocolo y el proveedor de seguridad para usar.
Aquí , puedo ver la lista de algoritmos que se pueden usar. ¿Qué algoritmo debería usar para habilitar la comunicación segura?
Además, dado que es posible especificar el proveedor de seguridad para usar, ¿qué proveedor debería usar?
Gracias
Como puede ver en la documentación de nombres estándar , todas las entradas (SSLv3, TLSv1.0, TLSv1.1, ...) dicen que pueden admitir otras versiones.
En la práctica, en Oracle JDK (y OpenJDK), todos lo hacen. Si observa el código fuente , la clase TLS10Context
es lo que se usa para TLS, SSL, SSLv3 y TLS10, TLS11Context
se usa para TLSv1.1 y TLS12Context
para TLSv1.2. Todos son compatibles con todas las versiones de SSL / TLS, es lo que está habilitado por defecto que varía.
Esto puede ser diferente con otro proveedor o proveedor de JRE. Por supuesto, debe elegir uno que al menos vaya a ser compatible con la versión de protocolo que desea utilizar.
Tenga en cuenta que el protocolo utilizado se determina más adelante utilizando SSLSocket.setEnabledProtocols(...)
o su equivalente SSLEngine
.
Como regla general, use el número de versión más alto que pueda (SSLv3 <TLSv1.0 <TLSv1.1 ...), que puede depender de las partes con las que desea comunicarse.
Los protocolos que están habilitados por defecto varían según la versión exacta de Oracle JRE.
Cuando se mira el código fuente de sun.security.ssl.SunJSSE
en OpenJDK 7u40-b43 , TLS
es simplemente un alias para TLSv1
(y también SSL
y SSLv3
), en términos de protocolos SSLContext
. Observando las diversas implementaciones de SSLContextImpl
(que son clases internas de SSLContextImpl
):
- Todos admiten todos los protocolos.
- Todos los protocolos están habilitados en el lado del servidor por defecto.
- los protocolos del lado del cliente habilitados por defecto varían:
-
TLS10Context
(utilizado para el protocoloSSL
,SSLv3
,TLS
,TLSv1
) habilita SSLv3 a TLSv1.0 de forma predeterminada en el lado del cliente. -
TLS11Context
(utilizado para el protocoloTLSv1.1
) también habilita TLSv1.1 de manera predeterminada. -
TLS12Context
(utilizado para el protocoloTLSv1.2
) también habilita TLSv1.2 de manera predeterminada.
-
- Si FIPS está habilitado, SSL no es compatible (por lo tanto, no está habilitado de manera predeterminada).
Esto cambia en Java 8, junto con la nueva propiedad del sistema jdk.tls.client.protocols
.
De nuevo, cuando miramos el código fuente de sun.security.ssl.SunJSSE
en OpenJDK 8u40-b25 , los protocolos TLSv1
, TLSv1.1
y TLSv1.2
también hacen uso de TLS10Context
, TLS11Context
y TLS12Context
, que siguen la misma lógica que en Java 7.
Sin embargo, el protocolo TLS
ya no tiene alias a ninguno de ellos. Por el contrario, utiliza TLSContext
que se basa en los valores de las propiedades del sistema jdk.tls.client.protocols
. De la guía de referencia de JSSE :
Para habilitar protocolos SunJSSE específicos en el cliente, especifíquelos en una lista separada por comas entre comillas; todos los demás protocolos compatibles se desactivan en el cliente. Por ejemplo, si el valor de esta propiedad es "TLSv1, TLSv1.1", las configuraciones de protocolo predeterminadas en el cliente para TLSv1 y TLSv1.1 están habilitadas en el cliente, mientras que SSLv3, TLSv1.2 y SSLv2Hello están deshabilitadas en el cliente.
Si esta propiedad está vacía, todos los protocolos están habilitados de forma predeterminada tanto en el lado del cliente como del servidor.
Por supuesto, en versiones recientes de Oracle JRE 8, SSL también está completamente deshabilitado por defecto (por lo que se elimina de esas listas).
Tenga en cuenta que en ambos casos (JRE 7 y 8), el SSLContext
que obtiene de forma predeterminada a través de SSLContext.getDefault()
es más o menos equivalente a un SSLContext
obtenido con el protocolo TLS
e inicializado con los parámetros de almacén de confianza predeterminados, etc. .
No hay un valor predeterminado para el protocolo, así que usaría el último compatible con su JDK, que es TLSv1, TLSv1.1 o TLSv1.2: vea cuál funciona, o eche un vistazo a getSupportedProtocols()
. El proveedor de seguridad predeterminado se utiliza al evitar todas las API donde lo especifique, o bien, por ejemplo, KeyStore.getDefaultType()
.
Y cuando vengas a obtener tus SSLEngines, asegúrate de usar el método que toma un nombre de host y un puerto. De lo contrario, no recibirá ninguna sesión de SSL compartida.