java - 没有服务器响应的 SSL 握手与 java 1.8

标签 java ssl jdbc sql-server-2012 sql-server-2014

我正在使用适用于 Microsoft SQL Server 2012 和 2014 的 Progress DataDirect(光荣...)JDBC 驱动程序。这两个服务器都是完全更新的 Windows 以及 SQL 服务器明智的。两者都强制加密。

我现在正尝试通过我的 java 客户端应用程序连接到它们,使用符合 FIPS 的信任库以及适当的 java.security 文件、jar、无限强度密码套件。信任库包含我自己的 CA 的自签名证书。使用的算法是RSA。

使用 JDK 1.7.0_21 它可以完美运行,但是当我更改为 1.8.0_74(最新的 afaik)时它会失败,因为 SQL 服务器不想在 ClientHello 之后回复。之后它只是通过连接重置断开连接。

此外,我已经尝试以不同的组合设置这些属性,独立的,但对 JDK 1.8 没有任何效果。

  • -Dhttps.protocols=TLSv1
  • -Dcom.sun.net.ssl.enableECC=false
  • -Djdk.tls.client.protocols=TLSv1

JDBC 连接属性也是开/关不同的组合:

  • 加密协议(protocol)版本=TLSv1.2
  • HostNameInCertificate=my.host.com

我尝试了 TLS 1.2、1.1 和 1,但没有任何效果。

因为它适用于 JDK 1.7,我倾向于认为 JDK 1.8 打破了这种机制。

JDK 1.8 的调试日志包含这个与 JDK 1.7 完全不同的日志条目

1.8:

Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

1.7

Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384

我还能尝试什么来解决这个问题?不幸的是,切换回 1.7 对我来说不是一个选择,也不可能。

编辑:

这是 -Djavax.net.debug=all 的最后一部分:

*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1440778452 bytes = { 133, 30, 185, 72, 50, 27, 253, 188, 73, 244, 59, 197, 169, 24, 142, 134, 78, 66, 122, 216, 60, 62, 232, 121, 107, 245, 32, 53 }
Session ID:  {}
Cipher Suites: [TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
Extension server_name, server_name: [type=host_name (0), value=my.sqlserver.com]
***
[write] MD5 and SHA1 hashes:  len = 130
<HEX DUMP>
main, WRITE: TLSv1.2 Handshake, length = 130
[Raw write]: length = 135
<HEX DUMP>

调用代码是这样的:

Connection connection = DriverManager.getConnection(url, getProps());

  private static Properties getProps()
  {
    Properties properties = new Properties();
    properties.setProperty("User", "sa");
    properties.setProperty("Password", "password");
    properties.setProperty("EncryptionMethod", "SSL");
    properties.setProperty("HostNameInCertificate", "my.sqlserver.com");
    properties.setProperty("TrustStore", "<Path to trust store");
    properties.setProperty("TrustStorePassword", "password");
    properties.setProperty("ValidateServerCertificate", "true");
    properties.setProperty("CryptoProtocolVersion", "TLSv1.2");

    return properties;
  }

最佳答案

对我来说,升级到 JDK8(更新 191)失败了 stricter policy for allowed (TLS) crypto algorithms .我只是通过修改我的 ${jdk.home}/jre/lib/security/java.security 文件再次启用了 3DES_EDE_CBC:

jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, \
    EC keySize < 224, 3DES_EDE_CBC

到:

jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \
    EC keySize < 224

或以编程方式:

java.security.Security.setProperty("jdk.tls.disabledAlgorithms", 
    "SSLv3, RC4, MD5withRSA, DH keySize < 768, EC keySize < 224");

或在 Spring :

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass" value="java.security.Security" />
    <property name="targetMethod" value="setProperty" />
    <property name="arguments">
        <list>
            <value>jdk.tls.disabledAlgorithms</value>
            <value>SSLv3, RC4, MD5withRSA, DH keySize &lt; 1024, EC keySize &lt; 224</value>
        </list>
    </property>
</bean>

另见 this answer related to SSLv3

关于java - 没有服务器响应的 SSL 握手与 java 1.8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35918910/

相关文章:

java - 文件上传字段 Wicket 错误

java - 同一个文件中的两个类

java - 使用 JDBC 准备好的语句插入时出错

java - Maven 找不到本地安装的包

java - 代码有什么区别?

ubuntu - Ubuntu 上托管的 LAMP 应用程序的 AWS SSL 证书

swift - brew : no formula called ctls

Apache - 安装 SSL 证书

postgresql - clojure.java.jdbc 惰性查询

Java SQL 问题