Java客户端SSL重新协商
我有一个Dropwizard应用程序,其中一个资源需要调用另一个Dropwizard应用程序上的资源。我们注意到在SSL重新协商上花费了很多时间。仔细检查后,仅当其他应用程序位于同一台机器上时,才会发生这种情况。即:Java客户端SSL重新协商,java,ssl,jersey,dropwizard,jersey-client,Java,Ssl,Jersey,Dropwizard,Jersey Client,我有一个Dropwizard应用程序,其中一个资源需要调用另一个Dropwizard应用程序上的资源。我们注意到在SSL重新协商上花费了很多时间。仔细检查后,仅当其他应用程序位于同一台机器上时,才会发生这种情况。即: client.target("https://mymachine.com/test").request().post(null); client.target("https://mymachine.com/test").request().post(null); // renego
client.target("https://mymachine.com/test").request().post(null);
client.target("https://mymachine.com/test").request().post(null);
// renegotiation
如果使用命令行选项-Djavax.net.debug=ssl:handshake:verbose
日志会显示
%% Client cached [Session-13, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256]
%% Try resuming [Session-13, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256] from port 55043
...
%% Invalidated: [Session-13, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256]
%% Initialized: [Session-15, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256]
但在本地计算机上调用同一服务时:
client.target("https://othermachine.com/test").request().post(null);
client.target("https://othermachine.com/test").request().post(null);
// SSL session re-use (=wanted)
日志上写着:
%% Client cached [Session-15, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
%% Try resuming [Session-15, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256] from port 55051
...
%% Server resumed [Session-15, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
这里发生了什么?结果是java版本不同。我的本地主机使用的是旧版本:-$ 爪哇™ SE开发工具包8,更新161(JDK 8u161)2018年1月16日 新功能 security libs/javax.net.ssl添加了TLS会话哈希和扩展主机 已为TLS会话添加机密扩展支持 JDK JSSE中的哈希和扩展主密钥扩展(RFC 7627) 供应商。请注意,通常情况下,服务器证书更改是无效的 如果未启用端点标识且上一个 握手是会话恢复,简称初始握手, 除非两个证书所代表的身份都可以被视为 同样的。但是,如果启用或协商扩展,则 服务器证书更改限制不是必需的,将被取消 因此被丢弃。在兼容性问题的情况下,应用程序 可以通过设置系统来禁用此扩展的协商 jdk中的属性jdk.tls.useExtendedMasterSecret为false。通过 将系统属性jdk.tls.AllowLegacyResumination设置为false时 当会话散列时,应用程序可以拒绝缩写握手 并且扩展的主密钥扩展是不协商的。通过设置 系统属性jdk.tls.allowLegacyMasterSecret为false,为 应用程序可以拒绝不支持会话的连接 散列和扩展主密钥扩展
参见JDK-8148421您是否注意到密码不同
TLS\u ECDHE\u RSA\u WITH_AES\u 128
CBC\u SHA256
vsTLS\u ECDHE\u RSA\u WITH_AES\u 128
GCM\u SHA256
因此,在协商TLS的方式上存在一些差异,CBC
实现不支持恢复
。你有一些挖掘工作要做。我们也有同样的问题。请注意,要重现这种情况,必须有两个Java应用程序直接相互通信(即,没有像Apache或nginx这样的反向代理)。第一个应用程序必须早于JDK 8u161,后者必须是JDK 8u161+。