GNU/Linux >> Tutoriales Linux >  >> Linux

Error de JDBC de SQL Server en Java 8:el controlador no pudo establecer una conexión segura con SQL Server mediante el cifrado de capa de sockets seguros (SSL)

Encendí el registro SSL en Java 8 JVM en una instancia de Linux que reproduce el problema. El registro SSL se activa con -Djavax.net.debug=ssl:handshake:verbose . Esto reveló información útil.

La solución alternativa que estamos usando en producción y ha demostrado que funciona para nosotros es establecer este parámetro en la JVM:

 -Djdk.tls.client.protocols=TLSv1

Si desea obtener más detalles, siga leyendo.

En un servidor donde se puede reproducir el problema (nuevamente, solo entre el 5 y el 10 % de las veces), observé lo siguiente:

*** ClientHello, TLSv1.2
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 195
main, READ: TLSv1.2 Handshake, length = 1130
*** ServerHello, TLSv1.2
--- 8<-- SNIP -----
%% Initialized:  [Session-79, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256]
** TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
--- 8<-- SNIP -----
Algorithm: [SHA1withRSA]
--- 8<-- SNIP -----
*** Diffie-Hellman ServerKeyExchange
--- 8<-- SNIP -----
*** ServerHelloDone
*** ClientKeyExchange, DH
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 133
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 108, 116, 29, 115, 13, 26, 154, 198, 17, 125, 114, 166 }
***
main, WRITE: TLSv1.2 Handshake, length = 40
main, called close()
main, called closeInternal(true)
main, SEND TLSv1.2 ALERT:  warning, description = close_notify
main, WRITE: TLSv1.2 Alert, length = 26
main, called closeSocket(true)
main, waiting for close_notify or alert: state 5
main, received EOFException: ignored
main, called closeInternal(false)
main, close invoked again; state = 5
main, handling exception: java.io.IOException: SQL Server returned an incomplete response. The connection has been closed. ClientConnectionId:12a722b3-d61d-4ce4-8319-af049a0a4415

Tenga en cuenta que TLSv1.2 es seleccionado por el servidor de la base de datos y utilizado en este intercambio. He observado que, cuando fallan las conexiones del servicio problemático de Linux, TLSv1.2 SIEMPRE es el nivel que se seleccionó. Sin embargo, las conexiones no SIEMPRE fallan cuando se usa TLSv1.2. Solo fallan del 5 al 10 % de las veces.

Ahora aquí hay un intercambio de un servidor que NO tiene el problema. Todo lo demás es igual. Es decir, conectarse a la misma base de datos, la misma versión de JVM (Java 1.8.0_60), el mismo controlador JDBC, etc. Tenga en cuenta que, aquí, TLSv1 es seleccionado por el servidor de la base de datos en lugar de TLSv1.2 como en el caso del servidor defectuoso.

*** ClientHello, TLSv1.2
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 207
main, READ: TLSv1 Handshake, length = 604
*** ServerHello, TLSv1
--- 8<-- SNIP -----
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
--- 8<-- SNIP -----
%% Initialized:  [Session-79, TLS_RSA_WITH_AES_128_CBC_SHA]
** TLS_RSA_WITH_AES_128_CBC_SHA
--- 8<-- SNIP -----
Algorithm: [SHA1withRSA]
--- 8<-- SNIP -----
***
*** ServerHelloDone
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
--- 8<-- SNIP -----
main, WRITE: TLSv1 Handshake, length = 134
main, WRITE: TLSv1 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 26, 155, 166, 89, 229, 193, 126, 39, 103, 206, 126, 21 }
***
main, WRITE: TLSv1 Handshake, length = 48
main, READ: TLSv1 Change Cipher Spec, length = 1
main, READ: TLSv1 Handshake, length = 48
*** Finished

Entonces, cuando se negocia TLSv1 entre Linux JVM y SQL Server, las conexiones SIEMPRE son exitosas. Cuando se negocia TLSv1.2, tenemos fallas de conexión esporádicas.

(Nota:Java 7 (1.7.0_51) siempre negocia TLSv1, razón por la cual nunca se nos presentó el problema con una JVM de Java 7).

Las preguntas abiertas que aún tenemos son:

  1. POR QUÉ es que la misma Java 8 JVM ejecutada desde 2 servidores Linux diferentes siempre negociará TLSv1, pero cuando se conecta desde otro servidor Linux siempre negocia TLSv1.2.
  2. Y también, ¿por qué las conexiones negociadas TLSv1.2 tienen éxito la mayor parte del tiempo, pero no todo, en ese servidor?

Actualización 10/06/2017: Esta publicación de Microsoft describe el problema y la solución propuesta.

Recursos:

http://www.infoworld.com/article/2849292/operating-systems/more-patch-problems-reported-with-the-ms14-066-kb-2992611-winshock-mess.html

http://www.infoworld.com/article/2849292/operating-systems/more-patch-problems-reported-with-the-ms14-066-kb-2992611-winshock-mess.html

http://blogs.msdn.com/b/jdbcteam/archive/2008/09/09/the-driver-could-not-establecer-a-secure-connection-to-sql-server-by-using-secure- sockets-layer-ssl-encryption.aspx

Java 8, política de fuerza ilimitada de JCE y protocolo de enlace SSL sobre TLS

http://blogs.msdn.com/b/saponsqlserver/archive/2013/05/10/analyzing-jdbc-connection-issues.aspx

https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2

https://blogs.oracle.com/java-platform-group/entry/java_8_will_use_tls


Esto parece haberse solucionado en la versión 4.2 del controlador MS SQL JDBC. Creé un programa donde me conecté al servidor 1000 veces, pausando 100 ms entre cada intento. Con la versión 4.1 pude reproducir el problema cada vez, aunque solo ocurría esporádicamente. Con la versión 4.2 no pude reproducir el problema.


Antes de actualizar el controlador JDBC de SQL, compruebe primero la compatibilidad:

  • Sqljdbc.jar requiere un JRE de 5 y es compatible con la API JDBC 3.0
  • Sqljdbc4.jar requiere un JRE de 6 y es compatible con la API JDBC 4.0
  • Sqljdbc41.jar requiere un JRE de 7 y es compatible con la API JDBC 4.1
  • Sqljdbc42.jar requiere un JRE de 8 y es compatible con la API JDBC 4.2

Fuente:https://www.microsoft.com/en-us/download/details.aspx?id=11774


Linux
  1. Cómo proteger su servidor ISPConfig 3 contra el ataque SSL de caniche

  2. Cómo arreglar Windows no pudo analizar o procesar el archivo de respuesta desatendido para Pass Specialize

  3. No se puede establecer la conexión usando ssh2_connect() en PHP

  4. ¿Tmux no obtiene el .tmux.conf?

  5. Error:no se pudo encontrar o cargar la clase principal

Cómo reparar el error de conexión SSH rechazada

Solución:no se puede establecer una conexión FTP a un servidor SFTP en FileZilla

Solución de problemas:errores de conexión del servidor

Error de FTP:no se pudo conectar al servidor:la política 534 requiere SSL

Reparación de error de tubería rota con conexión SSH

WSL - GEDIT No se puede iniciar el servidor:No se pudo conectar:​​Conexión rechazada