Pet*_*oss 5 java ssl jsse tomcat7
我有点困惑。我们已将 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" />
Run Code Online (Sandbox Code Playgroud)
我的 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
Run Code Online (Sandbox Code Playgroud)
建立连接后,我在浏览器窗口中右键单击,选择 Inspect Element 并选择 Network 标记,然后单击客户端请求。然后我选择了安全选项卡(用于请求)并显示:
Protocol verson: TLSv1.2
Cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Key Exchange group: None
...
Run Code Online (Sandbox Code Playgroud)
我确实注意到我们的证书已过期(我最初建立连接时收到安全异常)。
有人可以解释为什么协商密码不是 tomcat 密码列表中的密码之一吗?需要做什么来限制服务器支持的可用密码集?提前致谢。
结果:因此,启用日志记录后,服务器似乎确实在我们的连接密码列表中选择了一个密码。但是,当我检查 fire-fox 浏览安全设置时,浏览器表明它同意的密码是 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256。问题:
关于不可用的协议,您是否确认了Java中可用的密码?确认您的 Tomcat 使用的是您期望的 Java,如 Tomcat 的 JAVA_HOME 变量所定义。您可以通过编译一个简单的 Java 程序来获取 Java 中可用的密码套件的列表。(再次强调,请确保它是使用与 Tomcat 匹配的正确 Java 进行编译的。)Java 代码文件和说明可在此处找到,但为了完整起见,我将在下面将其包含在内。
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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
在某个临时文件夹中,将此文件另存为 Ciphers.java,然后使用以下命令进行编译:
javac Ciphers.java
Run Code Online (Sandbox Code Playgroud)
然后运行它:
java Ciphers
Run Code Online (Sandbox Code Playgroud)
它应该输出可用密码的列表。请注意,第一行Default Cipher不是语句,而是文本表的列标题(正如您可以在代码中读到的那样)。
一种可能性是您尝试使用的密码不在 Java 实现中,因此对 Tomcat 不可用。
第二种可能性是,由于您使用的证书,某些密码对您不可用。加密不是我的强项,但我相信您需要 RSA 密码的 RSA 证书。同样TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384需要 ECDSA 证书。请参阅此security.stackexchange问题和答案。所以这些密码中有一半可能对你不起作用。
您还可以使用 OpenSSL 的 sslscan 命令来测试哪些密码套件可用。(如果您不指定端口,它将假定为 443。)
sslscan localhost:8443
Run Code Online (Sandbox Code Playgroud)
它将帮助确定您是否已正确设置 Tomcat 连接器。但是,我怀疑它会匹配您的设置,并且不会解决您的客户端连接密码套件问题。(如果进行任何更改,请不要忘记重新启动 Tomcat 服务。我还发现重新启动服务后,在 sslscan 报告完整结果之前有一点延迟。要么等待,要么执行多次以确保确定。我认为 Tomcat 准备 Web 应用程序时超时。)
不幸的是,这个答案只解决了OP的一个子问题。我想看到主要问题的答案 - 我没有答案。希望其他人也能做到...
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |