我正在使用 Java 1.8 和 SQL Server 2008 R2(我完全知道它很长时间以来不受支持,但不幸的是它不在我手中),它仅支持 TLSv1。
我使用 ms-sql jdbc 连接到数据库并通过查询检索一些数据。设置 SQLServerDataSource 时,有一个选项可以启用/禁用加密:setEncrypt()。我使用完全相同的代码尝试了两种模式:
禁用加密后,连接成功(我可以通过此查询在 SQL 服务器端看到它:
SELECT * FROM sys.dm_exec_connections
和 encrypt_option = FALSE
),并且我可以运行查询来检索数据。
启用加密后,连接成功(我可以通过此查询在SQL服务器端看到它:
SELECT * FROM sys.dm_exec_connections
和encrypt_option = TRUE
),但在executeQuery()步骤我收到此错误:com.microsoft.sqlserver.jdbc.SQLServerException: SQL Server did not return a response. The connection has been closed.
我尝试了多个版本的 mssql-jdbc:6.2.2.jre8、8.2.2.jre8 和 12.8.0.jre8。同样的行为。
我还尝试通过 JDBC (
dataSource.setSSLProtocol("TLSv1")
) 或通过 java.security(Security.setProperty("jdk.tls.disabledAlgorithms", ...)
和 Security.setProperty("jdk.certpath.disabledAlgorithms", ...)
)调整 SSL 协议:没有影响。
知道什么可以解释这种行为吗?由于加密是触发器,我猜它与 TLS 协议有关,但我不明白为什么它只在查询执行步骤失败。
感谢您的帮助
我不确定为什么您会收到延迟错误并且不在连接上,但无论如何,我重新创建了您正在使用的设置。
问题是服务器和客户端必须在 TLS 级别上达成一致,并且您的客户端希望比服务器可以提供的最低级别更高。
在java 1.8中,至少在我的jdk上,禁用了以下TLS版本:TLSv1,TLSv1.1
如果您转到:
jdkhome\jre\lib\security\java.security
并查找jdk.tls.disabledAlgorithms
,您可以看到它的外观
如果您无法提高 TLS(您应该这样做),您可以做的就是降低 java 可以使用的最低 TLS 级别。
为此,您应该在应用程序中的某个位置创建添加自己的文件来覆盖此属性,例如:
sslenable.security
放这样的东西:
jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
include jdk.disabled.namedCurves
并使用以下 JVM 参数启动您的应用程序:
-Djava.security.properties=sslenable.security
这将创建连接,尽管我收到警告:
WARNING: TLSv1 was negotiated. Please update server and client to use TLSv1.2 at minimum.
你应该在某个时候这样做。