【发布时间】:2017-09-07 20:47:08
【问题描述】:
此问题与question pointed to 不重复。在提到的问题中没有任何关于 TLS 自身不执行主机名验证的事实。
我有 Java 中的 ActiveMQ 实例和客户端。客户端使用带有工厂 org.apache.activemq.ActiveMQSslConnectionFactory 的 JMSTemplate (org.springframework.jms.core.JmsTemplate)。我创建了自签名证书并使用它们信任存储和密钥库。两个程序都读取信任库和密钥库,我通过运行两个程序来检查它
-Djavax.net.debug=all
现在我的问题是客户端似乎完全忽略了服务器主机名验证。客户端使用 URL 连接到 ActiveMQ:
ssl://localhost:61616?jms.useCompression=true
现在,我尝试检查如果我更改 ActiveMQ 证书上的 CN 是否一切都会按预期失败,但结果并不顺利。我将 CN 改为例如:
CN=google.com
或到:
CN=some.random.xxx333aaa.net.pp
但所有这些值似乎都适用于 Java。另请注意,没有 SAN(即 subjectAltNames)。还有什么我试图用这样的证书连接到 ActiveMQ 但安装在不同的机器上,看起来一切正常。这不是我想要的。
另外:我终于卸载了所有 Java 版本并安装了 1.8.0_144,只使用 JDK 安装程序,在两个地方都安装了 jce_policy-8(它同时安装了 JRE 和 JDK),在远程机器上也做了同样的事情。
【问题讨论】:
-
您说客户端和服务器正在使用包含服务器证书的相同信任库。客户端将接受证书,因为它是“受信任的”,甚至是过期的,或者 CN 与服务器名称不对应。尝试仅从客户端信任库中删除它,然后连接将失败。这不是问题
-
@pedrofb 等等,你是不是想告诉我,仅仅因为我相信一些 CA,java 接受任何由该 CA 签名的证书,无论主机名是否有效?它不会与 PKI 似乎提供的功能完全相反吗?
-
@ElliottFrisch 谢谢,但它没有回答我的问题——我只想知道为什么默认情况下 Java 似乎不验证主机名。我认为应该这样做,因为否则人们不会寻找禁用此检查的方法。那么为什么它在我的情况下不起作用?我不知道,这就是我问的原因。
-
@pedrofb 我有一个主公钥/私钥对+证书,用于签署代理(ActiveMQ)的证书(带有私钥)和客户端(我的基于Spring的Java程序)的证书(也带有私钥) )。所以他们两个的信任库都包含主证书,他们各自的密钥库在证书中包含他们的公钥,并且都有他们的私钥。我使用 OpenSSL 创建了所有这些,将所有内容打包到 PKCS12 存储中,并将 PKCS12 导入 JKS。我认为这可以防止您提出的情况。但我想我找到了答案,请查看我的回复。
标签: java ssl certificate spring-jms