Java 如何在 Jetty 中禁用特定的 SSL 协议?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19913403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 21:15:55  来源:igfitidea点击:

How do I disallow particular SSL protocols in Jetty?

javassljettyopenjdksslv3

提问by Karl

I have a web application running on Jetty 6 + Open JDK 7 on Debian 6.0.7. I have a security requirement to accept a TLS handshake but notan SSLv3.0 handshake when a client initiates an HTTPS connection.

我有一个 Web 应用程序在 Debian 6.0.7 上的 Jetty 6 + Open JDK 7 上运行。当客户端启动 HTTPS 连接时,我有一个安全要求接受 TLS 握手但接受 SSLv3.0 握手。

In my jetty.xml I set the protocol to TLS:

在我的 jetty.xml 中,我将协议设置为 TLS:

<New class="org.mortbay.jetty.security.SslSocketConnector">
    <Set name="protocol">TLS</Set>
    ...

With this configuration, the web server still appears to accept an SSLv3.0 handshake. This has been verified with the 'sslscan' tool and running 'curl -sslv3 -kv {host}'.

使用此配置,Web 服务器似乎仍然接受 SSLv3.0 握手。这已经通过“sslscan”工具和运行“curl -sslv3 -kv {host}”进行了验证。

Is it possible to configure Jetty to only accept a TLS handshake? I would be willing to upgrade my Jetty version if needed.

是否可以将 Jetty 配置为仅接受 TLS 握手?如果需要,我愿意升级我的 Jetty 版本。

回答by Karl

I found two solutions:

我找到了两个解决方案:

Upgrade to Jetty 9, which supports the jetty.xml entry:

升级到 Jetty 9,它支持 jetty.xml 条目:

<Arg name="sslContextFactory">
    ...
    <Set name="excludeProtocols">
      <Array type="java.lang.String">
        <Item>SSLv3</Item>
      </Array>
     </Set>

Or, with Jetty 6 create delegate classes for SslSocketConnector and SSLServerSocketFactory:

或者,使用 Jetty 6 为 SslSocketConnector 和 SSLServerSocketFactory 创建委托类:

jetty.xml:
  ...
  <New class="com.src.TlsSocketConnector">
    ...
  </New>

public class TlsSocketConnector extends SslSocketConnector  {
  @Override
  protected SSLServerSocketFactory createFactory() throws Exception {
    return new TlsServerSocketFactory( super.createFactory() );
  }
}

public class TlsServerSocketFactory extends SSLServerSocketFactory {

  private SSLServerSocketFactory delegate;

  public TlsServerSocketFactory( SSLServerSocketFactory delegate ) {
    this.delegate = delegate;
  }

  //Repeat this pattern for all createServerSocket() methods
  public ServerSocket createServerSocket() throws IOException {
    SSLServerSocket socket = (SSLServerSocket) delegate.createServerSocket();
    socket.setEnabledProtocols( new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"});
    return socket;
  }

  // Directly delegated methods from SSLServerSocketFactory
  public String[] getDefaultCipherSuites() { return delegate.getDefaultCipherSuites(); }
  public String[] getSupportedCipherSuites() { return delegate.getSupportedCipherSuites(); }
}

回答by gageorge

For Jetty 6, you could also create an overridden SslSelectChannelConnector that removes SSLv3, like this:

对于 Jetty 6,您还可以创建一个删除 SSLv3 的覆盖 SslSelectChannelConnector,如下所示:

package com.mycompany;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.net.ssl.SSLEngine;

import org.mortbay.jetty.security.SslSelectChannelConnector;

public class SslSelectChannelConnectorNoSsl3 extends SslSelectChannelConnector {

  @Override
  protected SSLEngine createSSLEngine() throws IOException {
    SSLEngine engine = super.createSSLEngine();
    Set<String> protocols = new HashSet<String>(Arrays.asList(engine.getEnabledProtocols()));
    protocols.removeAll(Arrays.asList("SSLv2Hello","SSLv3"));
    engine.setEnabledProtocols(protocols.toArray(new String[protocols.size()]));
    return engine;
  }

}

And then specify that connector in jetty.xml, like this:

然后在 jetty.xml 中指定该连接器,如下所示:

<Call name="addConnector">
 <Arg>
   <New class="com.mycompany.SslSelectChannelConnectorNoSsl3">
   ...
   </New>
 </Arg>
</Call>