使用 Microsoft JDBC Driver 版本连接到 SQL Server 数据库时出现以下错误:
com.microsoft.sqlserver.jdbc.SQLServerException:驱动程序无法使用安全套接字层 (SSL) 加密建立与 SQL Server 的安全连接。错误:“SQL Server 返回不完整的响应。连接已关闭。ClientConnectionId:98d0b6f4-f3ca-4683-939e-7c0a0fca5931”。
我们最近将应用程序从 Java 6 和 Java 7 升级到 Java 8。所有运行 Java 的系统都在运行 SUSE Linux Enterprise Server 11 (x86_64),VERSION = 11,PATCHLEVEL = 3。
以下是我使用我编写的 Java 程序收集的事实,该程序只是按顺序打开和关闭 1,000 个数据库连接。
- 大约 5%-10% 的时间连接会因此错误而断开。错误不会发生在每个连接上。
- 该问题仅出现在 Java 8 上。我在 Java 7 上运行了相同的程序,但该问题无法重现。这与我们升级前的生产经验一致。在生产环境中,我们在 Java 7 下运行时遇到了零问题。
- 这个问题不会出现在我们所有运行 Java 8 的 Linux 服务器上,它只会出现在其中的一些服务器上。这让我很困惑,但是当我在不同 Linux 实例上的相同版本的 Linux JVM(1.8.0_60,64 位)上运行相同的测试程序时,在其中一个 Linux 实例上不会出现问题,但是问题确实发生在其他人身上。 Linux 实例运行相同版本的 SUSE,并且它们处于相同的补丁级别。
- 连接到 SQL Server 2008 和 SQL Server 2014 服务器/数据库时会出现此问题。
- 无论我使用的是 4.0 版本的 SQL Server JDBC 驱动程序还是更新的 4.1 版本的驱动程序,都会出现此问题。
与网络上的其他人相比,我对此的观察与众不同的是,尽管问题仅发生在 Java 8 上,但我无法在运行相同 Java 8 JVM 的看似相同的 Linux 服务器之一上出现问题。其他人也曾在早期版本的 Java 中看到过这个问题,但我们的经验并非如此。
感谢您提供的任何意见、建议或意见。
原文由 2Aguy 发布,翻译遵循 CC BY-SA 4.0 许可协议
我在重现问题的 Linux 实例上的 Java 8 JVM 中打开了 SSL 日志记录。使用
-Djavax.net.debug=ssl:handshake:verbose
打开 SSL 日志记录。这揭示了一些有用的信息。我们在生产中使用并已证明对我们有用的 解决方法 是在 JVM 上设置此参数:
如果您想了解更多详情,请继续阅读。
在可以重现问题的服务器上(同样,只有 5-10% 的时间),我观察到以下情况:
请注意,数据库服务器选择了 TLSv1.2 并在此交换中使用。我观察到,当有问题的 linux 服务连接失败时,TLSv1.2 始终是选择的级别。但是,使用 TLSv1.2 时,连接并不总是失败。他们只有 5-10% 的时间失败。
现在这是来自没有问题的服务器的交换。其他一切都是平等的。即,连接到相同的数据库、相同版本的 JVM(Java 1.8.0_60)、相同的 JDBC 驱动程序等。请注意,这里的数据库服务器选择的是 TLSv1 ,而不是故障服务器情况下的 TLSv1.2。
因此,当 Linux JVM 和 SQL Server 之间协商 TLSv1 时,连接总是成功的。协商 TLSv1.2 时,我们会遇到零星的连接失败。
(注意:Java 7 (1.7.0_51) 总是协商 TLSv1,这就是为什么我们在使用 Java 7 JVM 时从未出现过问题。)
我们仍有待解决的问题是:
2017 年 6 月 10 日 更新: Microsoft 发布的此帖子 描述了该问题及其建议的解决方案。
资源:
http://www.infoworld.com/article/2849292/operating-systems/more-patch-problems-reported-with-the-ms14-066-kb-2992611-winshock-mess.html
http://www.infoworld.com/article/2849292/operating-systems/more-patch-problems-reported-with-the-ms14-066-kb-2992611-winshock-mess.html
http://blogs.msdn.com/b/jdbcteam/archive/2008/09/09/the-driver-could-not-establish-a-secure-connection-to-sql-server-by-using-secure- sockets-layer-ssl-encryption.aspx
Java 8、JCE 无限强度策略和基于 TLS 的 SSL 握手
http://blogs.msdn.com/b/saponsqlserver/archive/2013/05/10/analyzing-jdbc-connection-issues.aspx
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2
https://blogs.oracle.com/java-platform-group/entry/java_8_will_use_tls