【问题标题】:Cannot connect to SQL Server server with MS JDBC Driver from CentOS 8 server: SSL error but not using secure connection无法从 CentOS 8 服务器使用 MS JDBC 驱动程序连接到 SQL Server 服务器:SSL 错误但未使用安全连接
【发布时间】:2020-10-16 08:02:52
【问题描述】:

我发现一篇文章与我遇到的问题很接近。就是这个:

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

我可以提供整个堆栈跟踪,但修剪后的版本有这一系列错误:

com.microsoft.sqlserver.jdbc.SQLServerException:驱动程序无法使用安全套接字层 (SSL) 加密建立与 SQL Server 的安全连接。错误:“java.security.cert.CertificateException:证书不符合算法约束”。 ClientConnectionId:e7a5ebc2-d489-4743-85ba-7873926508fe

原因:javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException:证书不符合算法约束

原因:java.security.cert.CertificateException:证书不符合算法约束

原因:java.security.cert.CertPathValidatorException:算法约束检查在密钥大小限制上失败。与证书一起使用的 RSA 1024 位密钥:CN=SSL_Self_Signed_Fallback。用法是 tls 服务器

JDBC 连接到一个没有启用连接加密或我知道的任何安全性的 SQL Server 2012。我和我们的数据库人员谈过,他说他知道的连接没有安全性。所以,我不确定为什么 MS 驱动程序继续抱怨 SSL 连接。

此 Linux 服务器 (CentOS 8) 有两个使用 JDBC 连接的 tomcat 安装。我有一个 Tomcat 8.0.32 实例,它使用 JTDS 驱动程序连接到 SQL Server 2012 实例,该驱动程序在连接上完全没有问题。我尝试将该驱动程序切换到 MS 驱动程序,然后它遇到了同样的错误。所以我把它换回来了。但是Tomcat(9.0.33)的第二次安装有一个需要JDBC 4.0或更高版本驱动程序的应用程序,而JTDS驱动程序只有3.0驱动程序,所以我必须使用MS驱动程序。但是,我不知道如何获得成功的连接。

通过互联网挖掘,我发现了对 jsse.jar 的引用并安装了正确的证书(尽管没有具体说明如何执行此操作或为什么这样做)。我还挖了一篇文章,说 JTDS 驱动程序使用 NTLM 进行连接(不是 100% 确定这一点,因为我在 JTDS 的连接中没有引用域)。无论如何,我只需要一些关于如何配置 MS 驱动程序以从 Linux 连接到不安全的 SQL Server 2012 的指导。我发现的 Microsoft 参考文献解决了安全连接,但没有关于不安全的连接。

运行 Java 版本:

  • openjdk 版本“1.8.0_252”

  • OpenJDK 运行时环境(内部版本 1.8.0_252-b09)

  • OpenJDK 64 位服务器 VM(内部版本 25.252-b09,混合模式)

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

也试过了:

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

只是:

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

有效的JTDS(在tomcat 8.0.32 / JDBC 3.0环境中):

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

任何可能为我指明正确方向的事情都会有所帮助,尤其是为什么 MS 驱动程序希望(或认为)连接是安全的。另一个花絮是我在部署到 Windows 10 时没有看到这些错误……所以它与 Linux 以及 Linux 上的 Java 配置有关。或者,也许我在 Linux 中只需要正确的连接字符串咒语.....

【问题讨论】:

  • 该错误表明服务器确实为 SSL(或:TLS)提供了带有 CN 'SSL_Self_Signed_Fallback' 的自签名证书,Java 不信任该证书。所以,也许你的 DBA 没有在 SQL Server 上配置 SSL,但它肯定是启用的。另见support.microsoft.com/en-us/help/2007728/…

标签: java sql-server linux ssl jdbc


【解决方案1】:

它必须与 java 的 openjdk 版本有关。我们已切换到 amazon correto 1.8,您可以在 here 找到它,并且一切正常。

【讨论】:

    【解决方案2】:

    花了不少时间解决centos 8与tomcat和jdbc:sql server 2014的连接问题。 我在 sql server 配置的协议属性中替换了自签名证书。 在 Windows 上看不到它是一种误导。它仅在 tomcat catalina.out 文件中可见 - 使用 -Djavax.net.debug=ssl:handshake:all 进行调试。 您必须准备来自权威机构的证书(自签名也应该工作)并将其存储在本地计算机中 - 自己的 Windows 服务器证书。 确保 sql server 的服务帐户对证书的私钥具有访问权限。否则sql服务不会启动。 重启sql server。

    将证书和链添加到您的 tomcat 配置 cacerts 文件中。 将-Djavax.net.ssl.trustStore=-Djavax.net.ssl.trustStorePassword= 添加到setenv.sh

    webapps web.xml 中的字符串必须简单如下: jdbc:sqlserver://yourURL;DatabaseName=yourDB;user=youruser;password=secret [其他选项不起作用并导致进一步的异常:integratedSecurity=true;encrypt=true;trustServerCertificate=true - trustStore=storeName;trustStorePassword=storePassword 我已经尝试了所有布尔选项,即:假/真] 重启tomcat

    【讨论】:

      【解决方案3】:

      所以,经过多次试验和错误后,我能够让它工作的方法是将 java.security 文件从 Windows 10 安装复制到 CentOS 8 安装。我可以看到两者之间唯一不同的是在本节中:

      '# 以该字符串开头或等于该字符串的逗号分隔包列表

      '# 时会引发安全异常

      '# 传递给 checkPackageDefinition 除非

      '#对应的RuntimePermission("defineClassInPackage."+package)有

      '# 被授予。

      '#

      '#默认情况下,JDK调用不提供任何类加载器

      '# checkPackageDefinition.

      '#

      CentOS 中的条目包括在列表末尾:

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

      Windows版本的条目最后只有一个条目:

                 com.sun.java.accessibility.
      

      这是我能找到的唯一区别。而且,我不明白为什么这会有所作为。但它现在确实连接没有错误,这就是我想要的......

      【讨论】:

      • 上述文件在哪里?
      • 找到/-name java.security
      【解决方案4】:

      驱动程序认为连接是安全的,如果它连接到一个只接收安全连接的端口。 1.检查端口 2.检查 JDBC url 上的任何其他显式 TLS/SSL 设置

      【讨论】:

      • 驱动程序不会被欺骗相信连接是安全的。它使用 TLS 连接并接收 default 自签名证书,然后 Java 代码不信任该证书。此默认自签名证书由 Microsoft SQL Server 安装或生成。因此,它实际上是使用 TLS 进行连接,但它并没有被“欺骗”相信连接是安全的(否则连接已经建立且没有错误,而是抛出 CertPathValidatorException 以指示不受信任的证书)
      • 被“欺骗”的驱动程序是一种说法,即驱动程序认为它需要启动安全连接。当发生 TLS 握手时,首先启动它的客户端。那么是什么告诉驱动程序它需要进行安全连接而不是不安全连接呢?它是在驱动程序本身上设置的配置参数。在大多数情况下是安全端口。
      • 感谢您的回复...我将在 MSSQL 方面进行更多研究,但为什么 JTDS 驱动程序使用相同的 URL(或多或少)从同一服务器连接到同一数据库而没有SSL 错误?如果 MSSQL 服务器被“意外”配置为使用安全连接,为什么在使用 JTDS 驱动程序时不强制执行该安全性?因此,其他一切都相同,只有驱动程序不同,JTDS 连接,MS 驱动程序抛出错误。不知何故,JTDS 在没有证书或 SSL 的情况下连接。
      • 您可以使用 '-Djavax.net.debug=ssl:handshake:verbose' 或 -Djavax.net.debug=ssl:handshake:all 在 JDBC 日志中找到答案。你能看一下吗,在检查日志之后,你可以查明导致这个问题的算法,然后编辑 java.security 文件中的 jdk.certpath.disabledAlgorithms=" 行
      • 但谜底是为什么?为什么 MS 驱动程序认为此连接是安全的?我检查了 SQL 服务器,没有任何迹象表明该服务器需要安全连接。连接 SQL Server 配置管理器中未配置证书。不检查强制协议加密。那么为什么驱动程序期望安全连接?有什么答案吗?我会看看日志说什么,但如果我知道为什么驱动程序认为它连接是加密的,当它不是我可以关闭它..?
      猜你喜欢
      • 2015-11-03
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      • 2019-12-26
      • 1970-01-01
      相关资源
      最近更新 更多