我们的服务器刚刚将其密码套件限制为:
SSLCipherSpec ALL TLS_RSA_WITH_AES_128_GCM_SHA256 TLS_RSA_WITH_AES_256_GCM_SHA384
现在我的测试 java 客户端代码失败,并在服务器日志中显示以下消息:
SSL 握手失败,未指定密码
客户端的这个堆栈跟踪:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.ibm.jsse2.j.a(j.java:42)
at com.ibm.jsse2.j.a(j.java:41)
at com.ibm.jsse2.qc.b(qc.java:485)
at com.ibm.jsse2.qc.a(qc.java:381)
at com.ibm.jsse2.qc.h(qc.java:453)
at com.ibm.jsse2.qc.a(qc.java:625)
at com.ibm.jsse2.qc.startHandshake(qc.java:113)
at com.ibm.net.ssl.www2.protocol.https.c.afterConnect(c.java:188)
at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:9)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1103)
at com.ibm.net.ssl.www2.protocol.https.b.getOutputStream(b.java:84)
谁能建议我需要在我的 HttpURLConnection 中设置什么才能让它使用这些受限制的密码套件? 或者这是我需要在 JVM 参数(在 Eclipse 中)中设置的东西吗?
非常感谢
您明显正在使用 IBM JSSE。根据其文档(请参阅定制 JSSE -> 定制),这可以通过设置 https.cipherSuites
系统属性来完成:
它包含一个以逗号分隔的密码套件名称列表,指定要在此
HttpsURLConnection
启用哪些密码套件。
这当然与Sun/Oracle JSSE完全相同的参数。(如果您还需要设置协议,您可能还会发现https.protocols
很有用。
如果要基于每个连接实现此目的,可以使用自定义SSLSocketFactory
将特定设置传递给HttpsURLConnection
。通常,您将实现自己的SSLSocketFactory
,将所有调用委托给默认SSLSocketFactory
(SSLSocketFactory.getDefault()
)或来自自定义SSLContext
的SSLSocketFactory
,但更改任何createSocket(...)
方法创建的SSLSocket
以更改其密码集。大致如下:
class MySSLSocketFactory {
public Socket createSocket(...) {
SSLSocket s = (SSLSocket) SSLSocketFactory.getDefault().createSocket(...);
s.setEnabledCipherSuites(...);
return s;
}
...
}
然后:
URLConnection urlConnection = url.openConnection();
HttpsURLConnection httpsUrlConnection = (HttpsURLConnection) urlConnection;
httpsUrlConnection.setSSLSocketFactory(new MySSLSocketFactory());
也就是说,您尝试使用的两个密码套件(TLS_RSA_WITH_AES_128_GCM_SHA256
和TLS_RSA_WITH_AES_256_GCM_SHA384
)仅在Java 8以来在Oracle JRE中受支持,但是默认情况下已经启用了它们,因此您不需要任何自定义。
IBM® SDK 的同一表,Java™ 技术版,版本 8 仅包含版本 7 之前的列,并且根本没有列出这些密码套件。我不确定这是否只是尚未更新的文档的一部分,或者 IBM JSSE 是否不支持这些密码套件,即使在版本 8 中也是如此。