我有点困惑。我们已将 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),您是否确认密码在 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/