我有点困惑。我们已经将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密码列表中的密码之一吗?需要做些什么来限制服务器支持的一组可用密码?预先感谢。
发现:因此,启用日志记录后,服务器似乎在我们的连接密码列表中选择了一个密码。但是,当我检查Firefox浏览器的安全性设置时,浏览器指示同意的密码是TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256。问题:
关于不可用的协议,您是否已确定Java中的密码可用?确认Tomcat使用的是您期望的Java,该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的一个子问题。我希望看到主要问题的答案-我没有一个。希望其他人可以...