SSLv3 error connecting JDBC to Sql Server 2012? - java

I've switched computers and installed mssql 2012sp2. (latest and greatest Win7 SP, sql server sp, etc)
When running sql via our ant scripts, I (surprisingly) had SSL handshake problems, with this error:
SSLv3 SSLContext not available
I'm using IBM JDK 1.6 and Microsoft's 2.0 jdbc driver from this file sqljdbc_2.0.1803.100_enu.tar.gz
Some data points
MSSQL jdbc drivers use SSL for login
We have production instances--using the same jdbc drivers--- pointing to MSSQL 2012. I had never seen this problem before.
I tried -Dhttps.protocols="TLS" without any success.
Some questions
Is this a post-POODLE change to MSSQL? Perhaps in a service pack?
Any workarounds?
thanks
Updated: Clarified I'm using IBM jdk, not Oracle's

The JDK version proved the cause--not sql server. I used a later version of the IBM JDK 1.6 on my new machine.
Specifically the later version of the IBM JDK disables SSLv3 by default.
Workaround
Add this option to the JVM
-Dcom.ibm.jsse2.disableSSLv3=false
Reference
http://www-01.ibm.com/support/docview.wss?uid=swg21688165#issues

Another option is to examine the SSL configuration of the SQL server you are attempting to contact, and make sure it is accepting TLS connections.
The SQL JDBC driver can also be in issue, as some older versions do not play
well with Java 1.7.

Related

When I try to connect to datasource in WildFly, it says Bad Handshake in error logs

When I try to connect to datasource in WildFly, it says Bad Handshake in MySQL error log and WildFly says:
Failed to add datasource of sql server in wildfly [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (XNIO-1 task-2) IJ000604: Throwable while attempting to get a new connection: null: javax.resource.ResourceException: Could not create connection
The reason is because my TLS version was incompatible, it was trying to use TLS 2, but my MySQL could only accept TLS 1.2. I've just started my job and the project is using legacy software, so for now were forced to use old software.
So my JDBC SQL connection was:
jdbc:mysql://localhost:3306/DATABASE_NAME
And this didn't work, but this did work:
jdbc:mysql://localhost:3306/DATABASE_NAME?enabledTLSProtocols=TLSv1.2
?enabledTLSProtocols=TLSv1.2 is what fixed my issue. Because my MySQL did not support TLS 2, it just didn't communicate well with my version of MySQL.
I am using 14.04 ubuntu linux and for some reason I had to install mysql 5.7.34 version, then the project I was working on gave me a Badhandshake error, I fixed my problem by adding the following in mysqld.cnf.
enabledTLSProtocols=TLSv1.2
Check out the following note from MySQL DEVS.
Note: As of MySQL 5.7.35, the TLSv1 and TLSv1.1 connection protocols
are deprecated and support for them is subject to removal in a future
version of MySQL. See Deprecated TLS Protocols.

Cannot connect to SQL Server server with MS JDBC Driver from CentOS 8 server: SSL error but not using secure connection

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.....
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
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....
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
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.
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

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

Background:
Application Server:
Java Based Application is running on Windows Server 2008 R2 Enterprise.
Java Version on this Server is Version 6 Update 32.
JDBC Driver Version: 4.0
Database Server:
The database server has been recently upgraded(Side by side upgrade with the same servername as the one before that the application use to connect to) from Windows 2016 to Windows 2019 and SQL Server 2012 to SQL Server 2016 and there is no Java on this server. Is this a problem??
History:
When we did the database server upgrade last time from SQL Server 2008 to SQL Server 2012, we followed the same method and the application worked fine.
But this time it is throwing the following error into the Application logs:
org.jboss.resource.JBossResourceException: Could not create connection; - nested throwable: (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.".)
We did not touch the application server at all, expecting that when the database server is up, since it is the same servername, it would start back up fine, but the application is failing with the above error.
There is no logon failure because we tested the application login and password and it worked fine.
I looked at the following:
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
but we cant seem to understand what is causing this issue since nothing on the Application Server has changed.
I looked at the compatibility between the JDBC Version and the SQL Server matrix here https://learn.microsoft.com/en-us/sql/connect/jdbc/microsoft-jdbc-driver-for-sql-server-support-matrix?view=sql-server-2017 and it looks like JDBC 4.0 works with SQL Server 2016.
Any ideas as to what could be going on?
Try adding "trustServerCertificate=true;" to the connection string example:
jdbc:sqlserver://NEUTRON\SQL2017;user=sa;password=password123;integratedSecurity=false;trustServerCertificate=true;
Ok, so we worked with Microsoft Support on this issue and this is the understanding that we came to.
Microsoft added/enabled TLS 1.0 and TLS 1.1 to the Database Server for testing purposes only since Microsoft does not support TLS 1.0 anymore. This lowered the security protocol to a lower state but were able to establish SQL Connectivity between the Application server and the Database Server, but still the Application initially couldn't connect. Microsoft thinks that it is because of the current connection provider/driver that is being used by the application and they wouldn't support that part of it since that is Java/Oracle's JDBC driver.
In our case, the application did connect after enabling the TLS 1.0 and TLS 1.1 after sometime.
This may or may not work in your case.
So the recommended solutions if you have the resources to modify the application, are to update the drivers for the application, test and redeploy.
If you don't have the resources to the application then the options are these:
1.Rollback to older Servers for SQL Server. This could work but there is no guarantee.
Also another thing to note is that SQL Server 2008 and 2008R2 are out of support, so the oldest we could go (and still stay supported) would be SQL Server 2012 which may not resolve the issue.
2.Open the security wide open. This will very likely solve the issue, but is most definitely not recommended. It is likely that the issue has to do with extremely outdated security providers, that are no longer supported. So, opening your security wide open will likely resolve the issue, but this is not recommended.
3.Rewrite the application which is not the easiest option, but is the only one that is fully recommended by Microsoft.
See this https://serverfault.com/questions/649052/do-i-have-to-enable-tls-1-0-in-windows-2008-r2 and this https://www.youtube.com/watch?v=vUuR_M3biDU if you'd like to enable TLS by yourself. The server will require reboot after you make this change.

How to connect to MSSQL Server with windows authentication and Force Encryption set to true

I was connecting to Sql Server 2008 & 2008+ via Java program with
Java 8
Sql jdbc microsoft driver 4.1
Connection string: DriverManager.getConnection("jdbc:sqlserver://<Ip>;instance=MSSQLSERVER;domain=<domain>;IntegratedSecurity=true;ssl=request;", "administrator", "password");
I was able to connect successfully.
However when I enabled Force encryption to true in the sql server via sql server configuration manager.
I started getting following error.
com.microsoft.sqlserver.jdbc.SQLServerException: An existing connection was forcibly closed by the remote host ClientConnectionId:xxxx
FYI:
I have already tried adding below parameters in connection string.
ssl=request
ssl=require
encrypt=true
trustServerCertificate=true
Also I have tried upgrading the driver to 4.2 & mssql driver 7.0
Tried jtds driver as well
Point to be noted: I am able to connect to instance via ssms
EDIT 1
- Another important point - It's happening only for windows authentication (enabled via IntegratedSecurity=true; in connection string).
So this case is happening only when Force encryption is set to true and we try to connect in windows authentication mode.
#Vivien #MarkRotteveel Thanks for your answers which gave me directions.
It turned out that sql server with version less then 11.0 were having troubles and various improvements were done as part of 11.0 version of sql server which rectified errors of windows authentication + encrypted connections connectivity.
So Sql server 2012 and above will support windows authentication with TLSv1.2, windows authentication along with encrypted connections seamlessly.
Now I am using
Java 8
Sql server driver 4.2
Windows 10
No extra parameters in connection string.
Just for reference: Found on Microsoft website.
It's unclear from your original question wether you have already done this, but if not, try setting both at the same time: encrypt=true;trustServerCertificate=true
Also, what do the SQL Server logs say?
I think Mark Rotteveel has right.
You need to check your version of both Java and SQL Server 2008.
TLS 1.2 has been enable by default in Java 8 since the u122, and appear in SQL Server 2008 only in the service pack 4 (version 10.0.6547.0, select ##VERSION; for check it)
If you don't meet the requierment, you have to choose between update the server or downgrade your jdk.
Perhaps their is an option in the JDK to retrieve the behavior prior to the update 122, but if it's the case, I don't know it.
And, for information, the mssql-jdbc driver has stop the support of SQL Server 2008 after the version 6.2.

Connect To SQL Server With Windows Authentication From A Linux Machine Through JDBC

I want to be able to connect to a SQL Server using jdbc and windows authentication.
I saw some answers on the internet saying i should add the following property to the connection string:
integratedSecurity=true;
And also add
sqljdbc_auth.dll
To the java path.
But this, as far as i understand applies only when i'm connecting from a Windows machine.
When i try this on a Linux machine i get:
java.sql.SQLException: This driver is not configured for integrated authentication
My question is how do I do it from a Linux machine.
Thanks
Well, eventually I answer my own question:
This is not possible to use Windows authentication from a linux machine using the Microsoft JDBC driver.
This is possible using the jTDS JDBC driver using the following connection string:
jdbc:jtds:sqlserver://host:port;databaseName=dbname;domain=domainName;useNTLMv2=true;
Thank you all for all the comments
TL;DR
It is not possible to use native Windows Authentication for JDBC connections to MSSQL from a JVM running on Linux.
This MSDN article explains the authentiation methods with JDBC on Linux, potential errors, and available options:
https://blogs.msdn.microsoft.com/psssql/2015/01/09/jdbc-this-driver-is-not-configured-for-integrated-authentication/
...in the JDBC 4.0 driver, you can use the authenticationScheme
connection property to indicate how you want to use Kerberos to
connect to SQL. There are two settings here.
NativeAuthentication (default) – This uses the sqljdbc_auth.dll and is specific to the Windows platform. This was the only option
prior to the JDBC 4.0 driver.
JavaKerberos – Makes use of the Java API’s to invoke kerberos and does not rely on the Windows Platform. This is java specific and not
bound to the underlying operating system, so this can be used on both
Windows and Linux platforms.
...
The following document outlines how to use Kerberos with the JDBC
Driver and walks through what is needed to get JavaKerberos working
properly.
Using Kerberos Integrated Authentication to Connect to SQL Server
http://msdn.microsoft.com/en-us/library/gg558122%28v=sql.110%29.aspx
For those who are using DBeaver the way to connect to the SQL Server Database is:
In order to connect to the SQL Server from Linux Debian using DBeaver
1.- Select SQL Server jTDS driver
2.- Enter the connection information
3.- Go to Driver Properties tab and add the domain, user, password
Just as a note, in some post I found that they needed to change the property USENTLMV2 to TRUE but it worked for me either by putting the USERTLNMV2 in true or false.
A problem that I found was that when I was trying to connect to the database using my user and password the next error was thrown:
Login failed. The login is from an untrusted domain and cannot be used with Windows authentication.
This error was thrown because of my user was about to expire. I tried with another AD user and it could connect.
I know this is kind of an older topic but in case Google sends people here:
There are two main JDBC drivers for SQL Server. One is from Microsoft and the other from jTDS. jTDS can, amazingly, connect using Windows auth (NTLM) from other platforms, including Linux, as described here: http://jtds.sourceforge.net/faq.html#windowsAuth. It can, of course, also use SQL-authenticated logins. SQL-authenticated logins are no harder to use from any OS than any other, so don't forget about those an option.
The version provided by Microsoft is the one from which #mjn provided a quote from the documentation. It is able to connect using Windows authentication by specifying integratedSecurity=true, authenticationScheme=javaKerberos, and authentication=NotSpecified.
It is tricky to get this working even if you don't go out of your way to find more confusion, so always keep in mind which driver you are using - and tell us in these posts so that you can get more specific help.
This JDBC URL is validated to work with latest Microsoft SQL Server JDBC driver:
jdbc:sqlserver://[server]:[port];database=[db\;trustServerCertificate=true;integratedSecurity=true;user=[user without domain];password=[pw];authenticationScheme=NTLM;domain=[domain];authentication=NotSpecified
Example:
jdbc:sqlserver://mysql.myorg.com:1433;database=mydb;trustServerCertificate=true;integratedSecurity=true;user=myuser;password=mypwd;authenticationScheme=NTLM;domain=ad.myorg.com;authentication=NotSpecified
I was able to connect to a SQL Server 2016 Data Mart and JDBC connection Microsoft JDBC Driver using Windows Authentication using the following script on a Ubuntu Linux Docker Image running on Windows 10.
# initializes spark session
from pyspark.sql import SparkSession
spark = SparkSession\
.builder\
.master('local[*]')\
.appName('FDM')\
.config("spark.driver.extraClassPath","pyspark_jars/*")\
.config('spark.executor.memory', '4g')\
.config('spark.driver.memory', '16g')\
.config('spark.executor.cores', '4')\
.getOrCreate()
jdbc_url = '''jdbc:sqlserver://SERVER;databaseName=DBNAME;trustServerCertificate=true;integratedSecurity=true;user=USERID;password=PASSWORD;authenticationScheme=NTLM;domain=US;authentication=NotSpecified'''
spark_df = spark.read\
.format("jdbc")\
.option("url", jdbc_url)\
.option("driver","com.microsoft.sqlserver.jdbc.SQLServerDriver")\
.option("query", 'select top(1000) * from SCHEMA.TABLE')\
.option("fetchsize", 100000)\
.load()
spark_df.write.csv('TEST.csv', mode = "overwrite", header=True)

Categories