Blog Post

SQL Server Support Blog
3 MIN READ

JDBC Connections fails with "The driver could not establish a secure connection to SQL Server...."

Krishnakumar_Rukmangathan's avatar
Apr 09, 2019

Issue:

 

While working on customer issue recently, I came across following scenario where there was a problem in connecting to the SQL Server from the IBM Java application (JDK 1.7) if we enable only TLS 1.2 protocol on both SQL and Application servers.

Let's say we have a simple java program build using the IBM JDK 1.7(pwa6470sr9fp50-20160720_02(SR9fp50)) to test the connectivity to the SQL Server by only enabling the TLS 1.2 protocol on both Application and SQL Server.

Java version as shown below.

 

Java Version

If we do a test connection to the SQL Server from the application server using the simple java program from the command prompt, it fails with the below error stack.

 

C:\JDK1.7\IBMJava70\bin>java -jar C:\DBConnTest\DBConnTest.jar

Using DB vendor -> MSSQL

Using the following properties:

Type:   MSSQL

 Host:   XXXXXXXX

 Port:   1433

 Name:   master

 User:   sa

 Pass:   XXXXXXXX

 Driver Path:    C:\DBConnTest\Drivers\jdbc41\sqljdbc_4.1\enu\jre7\sqljdbc41.jar

com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "SQL Server did not return a response. The connection has been closed. ClientConnectionId:7436e46e-1210-4052-92d2-0f2688b1e461".

        at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1669)

        at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1668)  at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1325)

        at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:993)

        at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:829)

        at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)

        at DriverShim.connect(DriverShim.java:14)

        at java.sql.DriverManager.getConnection(DriverManager.java:583)

        at java.sql.DriverManager.getConnection(DriverManager.java:227)

        at DBConnTest.main(DBConnTest.java:136)

Caused by: java.io.IOException: SQL Server did not return a response. The connection has been closed. ClientConnectionId:7436e46e-1210-4052-92d2-0f2688b1e461

        at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.ensureSSLPayload(IOBuffer.java:651)

        at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.readInternal(IOBuffer.java:708)

        at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.read(IOBuffer.java:700)

        at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.readInternal(IOBuffer.java:895)

        at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.read(IOBuffer.java:883)

        at com.ibm.jsse2.a.a(a.java:227)

        at com.ibm.jsse2.a.a(a.java:269)

        at com.ibm.jsse2.qc.a(qc.java:459)

        at com.ibm.jsse2.qc.h(qc.java:275)

        at com.ibm.jsse2.qc.a(qc.java:541)

        at com.ibm.jsse2.qc.startHandshake(qc.java:89)

        at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1618)

        ... 8 more

 

All done

 

Note: In the above case we are using the IBM JDK 1.7 with Microsoft JDBC driver 4.1 and you will experience the same issue for latest JDBC drivers (4.2,6.0,6.2) as well.

 

In the network trace analysis, we see that client initiates TLS handshake with a TLS1.0 Client Hello as shown below screen shot.

 

Network Trace Sample

Cause:

 

IBM JDK 1.7 supports the TLS 1.2 but still by default it uses the TLS 1.0 and for that reason we see that client application initiates TLS 3-way handshake with a TLS 1.0 client hello and connections are failing. 

The System property com.ibm.jsse2.overrideDefaultTLS is used to match the behavior of SSLContext.getInstance("TLS") in the IBM SDK.

com.ibm.jsse2.overrideDefaultTLS =[true|false]

To match the behavior of SSLContext.getInstance("TLS"), set this property to true. The default value is false.

Support

Solution:

 

We need to set the property com.ibm.jsse2.overrideDefaultTLS to True to enable the TLS 1.1 and TLS 1.2 in the IBM JDK.

To make a successful connection to the SQL Server from the application over TLS 1.2, we need to set the property com.ibm.jsse2.overrideDefaultTLS =true and pass it during run time as shown below.

 

C:\JDK1.7\IBMJava70\bin>java -jar -Dcom.ibm.jsse2.overrideDefaultTLS=true C:\DBConnTest\DBConnTest.jar

Using DB vendor -> MSSQL

Using the following properties:

 Type:   MSSQL

 Host:   XXXX

 Port:   1433

 Name:   master

 User:   sa

 Pass:   XXXXXXX

 Driver Path:    C:\DBConnTest\Drivers\jdbc41\sqljdbc_4.1\enu\jre7\sqljdbc41.jar

 Connection successful.

 

 

Author:  SatyaSai K – Support Engineer, SQL Server BI Developer team, Microsoft 
Reviewer: Krishnakumar Rukmangathan - Support Escalation Engineer, SQL Server BI Developer team, Microsoft

Updated Apr 09, 2019
Version 2.0
  • yycelik's avatar
    yycelik
    Copper Contributor

    it works for liberty

    Go to one of the following directories and open the jvm.options file.

    -Dcom.ibm.jsse2.overrideDefaultTLS=true

  • JorgeL-0's avatar
    JorgeL-0
    Copper Contributor

    It works for IBM Integration bus 10, just set -Dcom.ibm.jsse2.overrideDefaultTLS=true in  JVM system properties of the integration server.