6

I found one article that was close to the issue I am experiencing. It is this one:

SQL Server JDBC Error on Java 8: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption

I can provide the entire stack trace but the pruned version has this series of errors:

com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "java.security.cert.CertificateException: Certificates do not conform to algorithm constraints". ClientConnectionId:e7a5ebc2-d489-4743-85ba-7873926508fe

Caused by: javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException: Certificates do not conform to algorithm constraints

Caused by: java.security.cert.CertificateException: Certificates do not conform to algorithm constraints

Caused by: java.security.cert.CertPathValidatorException: Algorithm constraints check failed on keysize limits. RSA 1024bit key used with certificate: CN=SSL_Self_Signed_Fallback. Usage was tls server

The JDBC connection is to a SQL Server 2012 that does NOT have connection encryption enabled or any security that I know of. I talked to our DB guy and he says there is no security on the connection that he knows of. So, I am not sure WHY the MS driver continues to complain about the SSL connection.

This Linux server (CentOS 8) has two tomcat installations that use JDBC connections. I have a Tomcat 8.0.32 instance that connects to the SQL Server 2012 instance using the JTDS driver that has no problem at all in connecting. I tried switching that driver to the MS driver and it then experienced the same errors. So I switched it back. But the second installation of Tomcat (9.0.33) has an app that requires a JDBC 4.0 or above driver and the JTDS driver is only a 3.0 driver so I have to use the MS driver. But, I cannot figure out how to get a successful connection.

Digging through the Internet I found reference to the jsse.jar and having the correct certs installed (although nothing specific as to how to do it or why). I also dug of an article that said that the JTDS driver uses NTLM to connect (not 100% sure about that since I have no reference to a domain in my connection for JTDS). In any case, I just need some guidance on how to configure the MS driver to connect from Linux to a non-secured SQL Server 2012. The Microsoft references I found addressed secured connections but nothing about connections that were not secured.

Running Java version:

  • openjdk version "1.8.0_252"

  • OpenJDK Runtime Environment (build 1.8.0_252-b09)

  • OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)

    driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver url=jdbc:sqlserver://192.168.80.214:1433;databaseName=DB_Central;
    integratedSecurity=true;authenticationScheme=NTLM;domain=mydomain.org;

Also tried:

url=jdbc:sqlserver://192.168.80.214:1433;databaseName=DB_Central;encrypt=false;sslProtocol=TLSv1.2;

And just:

url=jdbc:sqlserver://192.168.80.214:1433;databaseName=DB_Central

JTDS that works (in the tomcat 8.0.32 / JDBC 3.0 environment):

driverClassName=net.sourceforge.jtds.jdbc.Driver
url=jdbc:jtds:sqlserver://192.168.80.214:1433;databaseName=DB_Central

ANYTHING that might point me in the right direction would be helpful especially why the MS driver wants (or thinks) the connection is secure. The other tidbit is that I see none of these errors when deployed to Windows 10...so it has something to do with Linux and maybe the Java config on Linux. Or, maybe I just need the correct incantation for the connection string when in Linux.....

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Pete Helgren
  • 438
  • 1
  • 7
  • 21
  • The error indicates that the server does provide SSL (or: TLS) with a self-signed certificate with CN 'SSL_Self_Signed_Fallback', which isn't trusted by Java. So, maybe you DBA didn't configure SSL on SQL Server, but it is definitely enabled. See also https://support.microsoft.com/en-us/help/2007728/error-message-when-you-use-ssl-for-connections-to-sql-server-the-certi – Mark Rotteveel Jun 26 '20 at 06:09

5 Answers5

0

The driver believes that the connection is secure , if it is connecting to a port that is meant to receive only secure connections. 1.Check the port 2.Check for any other explicit setting of TLS / SSL on the JDBC url

  • The driver isn't tricked into believing the connection is secure. It is connecting using TLS and receiving a **default** self-signed certificate, which then isn't trusted by the Java code. This default self-signed certificate is installed or generated by Microsoft SQL Server. So, it is actually connecting using TLS, but it isn't 'tricked into' believing the connection is secure (otherwise the connection had been made without error, instead a CertPathValidatorException is thrown to indicate an untrusted certificate) – Mark Rotteveel Jun 26 '20 at 06:10
  • The driver being "tricked" is a way of saying that the driver believes it needs to initiate a secure connection.When a TLS handshake happens , its the Client that initiates it first. So what is it that tells the driver that it needs to go for a secure connection and not an insecure one ? Its the configuration params that are set on the Driver itself. Which in -most cases is the secure port. – smithapambalath Jun 26 '20 at 10:42
  • Thanks for the replies...I'll dig more on the MSSQL side but why does the JTDS driver connect from the same server to the same DB with the same URL (more or less) without an SSL error? If the MSSQL server was "accidentally" configured to use a secure connection, why isn't that security enforced when the JTDS driver is used? So, everything else being equal and only the driver being different, JTDS connects, the MS driver throws the error. Somehow JTDS connects without a certificate or SSL. – Pete Helgren Jun 26 '20 at 17:31
  • you can find the answer to this in the JDBC logs for both with '-Djavax.net.debug=ssl:handshake:verbose' or -Djavax.net.debug=ssl:handshake:all . Could you take look at that, after checking the logs , you can pin point the Algorithm that is casuign this issue ans then edit the jdk.certpath.disabledAlgorithms=" line in the java.security file – smithapambalath Jun 27 '20 at 04:44
  • 1
    But the mystery is WHY? WHY is this connection viewed by the MS driver as secure? I checked the SQL server and there is NOTHING that indicates this server requires a secure connection. There isn't a certificate configured in the connection SQL Server Configuration Manager. Force protocol encryption is NOT checked. So WHY is the driver expecting a secure connection? Any answer to that? I'll see what the logs say but if I knew why driver thought it the connection was encrypted when it isn't I could turn it off..? – Pete Helgren Jun 27 '20 at 19:39
  • So, still stuck. One MS article mentions: When the encrypt property is set to true and the trustServerCertificate property is set to true, the Microsoft JDBC Driver for SQL Server won't validate the SQL Server TLS certificate. No joy, still fails. The cert chain is below with some bits removed so it would fit chain [0] = [ [ Version: V3 Subject: CN=SSL_Self_Signed_Fallback Signature Algorithm: SHA1withRSA, Key: Sun RSA public key, 1024 bits ] Issuer: CN=SSL_Self_Signed_Fallback ] Algorithm: [SHA1withRSA] Signature: ] – Pete Helgren Jun 28 '20 at 21:54
0

So, the way I was able to get this to work after much trial and error was to copy the java.security file from the windows 10 install to the CentOS 8 install. The ONLY thing I can see as different between the two was in this section:

'# List of comma-separated packages that start with or equal this string

'# will cause a security exception to be thrown when

'# passed to checkPackageDefinition unless the

'# corresponding RuntimePermission ("defineClassInPackage."+package) has

'# been granted.

'#

'# by default, none of the class loaders supplied with the JDK call

'# checkPackageDefinition.

'#

The entries in CentOS included at the end of the list:

           org.GNOME.Accessibility.,\
           org.GNOME.Bonobo.

The entries in the Windows version had only one entry at the end:

           com.sun.java.accessibility.

That was the only difference I could find. And, I don't understand why that made a difference.. But it DOES connect without error now and that is all I wanted....

Pete Helgren
  • 438
  • 1
  • 7
  • 21
0

spend quite some time to solve the connection issues between centos 8 with tomcat and jdbc:sql server 2014. I replaced the self-signed certificate in the properties of protocols in sql server configuration. It is misleading that you can't see it on windows. It's only visible in the tomcat catalina.out file - use debug with -Djavax.net.debug=ssl:handshake:all. You have to prepare a certificate from an authority (a self-signed should also work) and store it in local computer - own certificate of the windows server. Make sure the service account of sql server has access right on the private key of the certificate. Otherwise, the sql service will not start. Restart sql server.

Add the certificate and chain to your tomcat configuration cacerts file. add -Djavax.net.ssl.trustStore= and -Djavax.net.ssl.trustStorePassword= to setenv.sh

The string in the webapps web.xml had to be as simple as: jdbc:sqlserver://yourURL;DatabaseName=yourDB;user=youruser;password=secret [other options did not work and led to further exceptions: integratedSecurity=true;encrypt=true;trustServerCertificate=true - trustStore=storeName;trustStorePassword=storePassword and i've tried all boolean options i.e.: false/true] Restart tomcat

Rayan Ral
  • 1,862
  • 2
  • 17
  • 17
0

It has to do something with openjdk version of java. We have switched to amazon correto 1.8 you can find it here, and everything worked perfectly.

tibortru
  • 692
  • 5
  • 26
0

If anyone having the same problem at a Redhat 8 Linux, below command worked for me (it lowers the security)

update-crypto-policies --set LEGACY