The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption.

What is SSL and why is my JDBC driver using it?

The v1.2 JDBC driver uses SSL (Secure Sockets Layer) to encrypt connections to SQL Server for improved security. Where it can, the v1.2 driver ALWAYS uses SSL to encrypt the login to SQL Server. For integrated auth connections, SSL provides an added layer of security. For SQL auth, where the user name and password would otherwise be sent in the clear, SSL provides an essential layer of security.

 

I trust that my network is secure without SSL... How do I turn off SSL encryption?

You can control whether a connection encrypts all data to and from the server after login using the ‘encrypt’ connection property. However, where it can, the v1.2 driver ALWAYS uses SSL to encrypt the login to SQL Server. You cannot disable SSL encryption of the SQL Server login.

 

Ok, but I upgraded to v1.2 and now I can’t connect! Why am I getting the error “The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: …”?

Odds are good that your Java SSL setup is messed up somehow.

 

SSL in Java is provided through the Java Secure Socket Extension (JSSE). Its reference guide (for J2SE 5) is here: https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html . A key aspect of JSSE is its pluggable provider model. Typically, JRE vendors supply JSSE provider implementations. There are at least two main JSSE providers available out there and they do not necessary work well together.

 

For SSL to work at all, it is absolutely necessary to have the JSSE providers configured correctly for the JRE you are using. There are two steps to this:

1) Look at the java.security file in your JRE installation (typically found in the jre\lib\security directory). The installed security providers are listed in that file as security.provider.x=… where ‘x’ is the priority used. For Sun JRE installations, the first priority provider should be Sun’s. E.g.: you should have the line “security.provider.1=sun.security.provider.Sun” in that file. For other JRE's, please refer to the JRE's documentation regarding their default provider name. We recommend when using the IBM JRE to specify the "com.ibm.jsse.IBMJSSEProvider" as the first security provider to use.

2) Next, make sure that the classpath points to the correct JAR files (in the jre\lib directory) for use with those providers. For Sun, the classpath should include jsse.jar. For IBM, should include ibmjsse.jar.

 

If either the classpath or the java.security file is not correct, SSL will not work. Not just with SQL Server, but with anything else either.

 

SSL works for other apps, just not with JDBC. And I’ve verified that the classpath is correct… Check certificates

If you are going to configure SQL Server to use a server certificate, then that certificate needs (or the certificate of one of its trusted issuing authorities) needs to be present in Java’s certificate store. If the certificate isn’t there, chances are that your JSSE provider will give you a nice descriptive, if sometimes cryptic, error. Configuring the client for use with SSL is covered in our docs here https://msdn2.microsoft.com/en-us/library/bb879943.aspx . Some certificates are quite large and trip up older JSSE providers. Of course there may be other VMs out there with similar problems, but we are not able to verify all of them. A smaller certificate may help in this case.

 

Not a configuration problem or a certificate problem. Now what.

When contacting Microsoft to help us be effective, we need to be armed with the following info:

1) The complete text of the error message. I.e. including the part after “Error: …” above.

2) A stack trace (if available).

3) A complete log (if available) containing FINEST TDS-level traces leading up to the error. In particular, the following loggers should be enabled in the logging properties:

com.microsoft.sqlserver.jdbc.TDSChannel.level = FINEST

com.microsoft.sqlserver.jdbc.TDSReader.level = FINEST

com.microsoft.sqlserver.jdbc.TDSWriter.level = FINEST

com.microsoft.sqlserver.jdbc.TDS.DATA.level = FINEST

               Generating the log file with the XMLFormatter is preferred over SimpleFormatter, as it gives us more info.

4) The java.security file that was used.

5) Vendor and version of the JRE used.

6) SQL Server version

7) The connection string/connection properties used.

David Olix & Jimmy Wu

SQL Server JDBC Team