java - Firefox 浏览器/服务器协商的选定密码与 Tomcat 配置的密码列表不匹配

标签 java ssl tomcat7 jsse

我有点困惑。我们已将 v7 Tomcat 服务器配置为仅使用 TSLv1.2 与连接的浏览器进行通信,并且我们指定了一组受限密码。使用 Firefox 浏览器(v60.3.0esr 64 位)。我们能够建立连接,但奇怪的是,在我连接到站点后,我注意到商定的密码不在配置的 tomcat 密码列表中。

我的印象是,在配置 http 连接对象时,服务器作为 hello 连接否定的一部分会将连接限制为可​​用密码列表?我错过了什么?如果缺少 ciphers 参数,那么可用密码列表将仅限于 JVM 上配置的密码(这是我的理解)。因此,我是否还需要将 JVM 中的密码限制为我在 http 连接器元素中指定的同一组?

细节:
Tomcat (v 7.0.77 java 1.8.0_151)

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true" allowTrace="false"
clientAuth="false" sslProtocols="TLS" sslEnabledProtocols="TLSv1.2"
keystoreFile="/etc/tomcat/tomcat.keystore" keystorePass="XXXX"
ciphers="TLS_RSA_WITH_AES_256_CBC_SHA256,
         TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
         TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
         TLS_RSA_WITH_AES_128_CBC_SHA256, 
         TLS_RSA_WITH_AES_128_CBC_SHA,
         TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
         TLS_RSA_WITH_AES_256_GCM_SHA384,
         TLS_RSA_WITH_AES_128_GCM_SHA256,
         TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
         TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
         TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
         TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384" />

我的 tomcat.config 中没有任何具体定义
    JAVA_HOME="/usr/lib/jvm/jre"
    CATALINA_BASE="/usr/share/tomcat"
    CATALINE_HOME="/usr/share/tomcat"
    JASPER_HOME="/usr/share/tomcat"
    CATALINE_TMPDIR="/var/cache/tomcat/temp"
    TOMCAT_USER="tomcat"
    SECURITY_MANAGER="false"
    SHUTDOWN_WAIT="30"
    SHUTDOWN_VERBOSE="false"
    CATALINA_PID="/var/run/tomcat.pid

建立连接后,我在浏览器窗口中单击鼠标右键,选择“检查元素”并选择“网络”标签并单击客户端请求。然后我选择了安全选项卡(用于请求)并显示:
     Protocol verson: TLSv1.2
     Cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
     Key Exchange group: None
     ...

我确实注意到我们的证书已经过期(我在最初建立连接时收到了一个安全异常)。

有人可以解释为什么协商的密码不是tomcat密码列表中的密码之一吗?需要做什么来限制服务器支持的可用密码集?提前致谢。

结果:因此,启用日志记录后,服务器似乎确实在我们的连接密码列表中选择了一个密码。但是,当我检查 fire-fox 浏览安全设置时,浏览器表明它同意密码是 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256。问题:
  • 关于协议(protocol)处理程序的初始化,为什么会有这么多协议(protocol)不可用?这个 Tomcat 是否正在研究 JVM,并且由于某种原因,JVM 没有这些协议(protocol)集。我们不包括必需的库吗?
  • 我可以在日志中看到客户端/服务器 hello 消息交换和商定的密码。然而浏览器显示不同的密码,这是如何变化的?有什么东西在拦截这种交流吗?至少可以说很困惑。任何想法?
  • 最佳答案

    关于不可用的协议(protocol),您是否确认密码在 Java 中可用?确认您的 Tomcat 正在使用您期望的 Java,由 Tomcat 的 JAVA_HOME 变量定义。您可以通过编译一个简单的 Java 程序来获得 Java 中可用密码套件的列表。 (再次,确保它使用与 Tomcat 匹配的正确 Java 编译。)Java 代码文件和说明可用 here ,但为了完整起见,我将其包含在下面。

    import java.util.Iterator;
    import java.util.Map;
    import java.util.TreeMap;
    import javax.net.ssl.SSLServerSocketFactory;
    
    public class Ciphers
    {
        public static void main(String[] args)
            throws Exception
        {
            SSLServerSocketFactory ssf = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
    
            String[] defaultCiphers = ssf.getDefaultCipherSuites();
            String[] availableCiphers = ssf.getSupportedCipherSuites();
    
            TreeMap ciphers = new TreeMap();
    
            for(int i=0; i<availableCiphers.length; ++i )
                ciphers.put(availableCiphers[i], Boolean.FALSE);
    
            for(int i=0; i<defaultCiphers.length; ++i )
                ciphers.put(defaultCiphers[i], Boolean.TRUE);
    
            System.out.println("Default\tCipher");
            for(Iterator i = ciphers.entrySet().iterator(); i.hasNext(); ) 
            {
                Map.Entry cipher=(Map.Entry)i.next();
    
                if(Boolean.TRUE.equals(cipher.getValue()))
                    System.out.print('*');
                else
                    System.out.print(' ');
    
                System.out.print('\t');
                System.out.println(cipher.getKey());
            }
        }
    }
    

    在某个临时文件夹中,将此文件另存为 Ciphers.java,并使用以下命令进行编译:
    javac Ciphers.java
    

    然后运行它:
    java Ciphers
    

    它应该输出可用的密码列表。注意 Default Cipher 的第一行不是语句,而是文本表的列标题(您可以在代码中阅读)。

    一种可能性是您尝试使用的密码不在 Java 实现中,因此对 Tomcat 不可用。

    第二种可能性是由于您使用的证书,某些密码对您不可用。加密不是我的强项,但我相信您需要 RSA 证书才能使用 RSA 密码。同样TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384需要 ECDSA 证书。看到这个security.stackexchange问题和答案。所以这些密码中有一半可能对你不起作用。

    您还可以使用 OpenSSL 的 sslscan 命令来测试可用的密码套件。 (如果您不指定端口,它将假定为 443。)
    sslscan localhost:8443
    

    这将有助于确定您是否正确设置了 Tomcat 连接器。但是,我怀疑它会与您的设置相匹配,而不是解决您的客户端连接密码套件问题。 (如果您进行任何更改,请不要忘记重新启动 Tomcat 服务。我还发现在 sslscan 报告完整结果之前重新启动服务后会有一点延迟。请等待或多次执行以确保。我认为当 Tomcat 准备 Web 应用程序时它会超时。)

    不幸的是,这个答案只解决了 OP 的一个子问题。我想看看主要问题的答案——我没有。希望别人会...

    关于java - Firefox 浏览器/服务器协商的选定密码与 Tomcat 配置的密码列表不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53823977/

    相关文章:

    java - 根据值将数据集分组为不同的子数据集

    c# - 使用 .Net Standard 2.0 库中的 x509 证书使用 WCF Web 服务?

    azure - Win2012R2 新自签名证书 : A parameter cannot be found that matches parameter name 'Provider'

    jsf - Tomcat @Resource 注释 API 注释在 Tomcat 7 中停止工作

    tomcat - 如何在 Tomcat 7 0 39 上运行的 Grails 2.2 中设置 MaxPermSize?

    java - 取消我没有写的动态加载的 Callable

    java-如何使用服务发送电子邮件?

    ruby-on-rails - 带有 Nginx 和 SSL 握手的 Websockets

    java - Tomcat 7 上的 URL 丢失应用程序名称

    java - 如何转换标记(字符串中的八进制表示)