【发布时间】:2013-10-11 17:24:56
【问题描述】:
我对使用 http/certs/etc 还是很陌生。我为 apache httpclient 设置了自己的 hostnameVerifier。 (试图让 FQDN 不匹配,只要证书 FQDN 仍然在我们的域内部 - 不是我所知道的最好的 - 但总比没有好)
它适用于我测试过的大多数服务器,但有几个我得到了
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
当我尝试时
session.getPeerCertificateChain().
当我转到 Firefox 中的同一个链接时,我可以很好地查看证书。
以下是该方法的完整代码。
@Override
public void verify( String arg0, SSLSocket arg1 ) throws IOException
{
String certFQDN = null;
SSLSession session = arg1.getSession();
javax.security.cert.X509Certificate[] certs = session.getPeerCertificateChain();
if ( certs.length > 0 )
{
String name = certs[ 0 ].getSubjectDN().getName();
for ( String s : name.split( "," ) )
{
String part[] = s.split( "=" );
if ( part[ 0 ].trim().equals( "CN" ) )
{
certFQDN = part[ 1 ].trim();
}
}
}
else
{
throw new IOException( "Could not find certificate chain." );
}
if ( !certFQDN.substring( certFQDN.length() - 11 ).equals( ".domain.com" ) )
{
throw new SSLException( "Not an internal host: " + certFQDN );
}
}
【问题讨论】:
-
"试图让 FQDN 不匹配,只要他们指向的 IP 匹配":这实际上容易受到 MITM 攻击(通过 DNS)。
-
这是当前使用的代码的一个进步,它允许这些服务器所在的主域的任何子域。此代码在没有我们自己的公司的情况下以非常有限的方式使用。如果我可以让所有服务器管理员获取他们的证书,以便我可以进一步收紧。在那之前——这是我能做的最好的。现在我考虑了一下……如果有人在控制 DNS,那么检查 FQDN 是否匹配比检查 IP 是否匹配更好。如果他们控制 DNS,他们不能欺骗他们想要的任何服务器名称吗?我完全相信你比我更了解这一点,我只是想了解。 :)
-
嗯,不是真的。正确的主机名验证的要点是在存在 MITM 时防止 MITM。如果你假设没有一个,那么就没有问题。如果有 MITM,他可以欺骗您的反向 DNS 请求。如果你想要阻止 MITM 攻击,那么半途而废是没有意义的。
-
检查证书中的 FQDN 是不同的:您知道要在 URL 中联系的主机名。如果 MITM 攻击者欺骗了您的转发 DNS 请求,他们不会将您引导到具有与预期名称匹配的受信任证书的机器。在这里,根据您的逻辑,您没有固定的参考来比较证书的内容:certIP 和 connectionIP 都可能在 MITM 的控制之下。
-
这是有道理的。如果我放弃 IP 检查,而是检查给定证书中的域是否是我们的子域。有人可以欺骗 DNS 但无法访问我们子域之一的证书是否可行?如果是这样,即使它仍然容易受到内部 MITM 攻击,这是否至少会清除那些潜在的 MITM 攻击?
标签: java ssl https httpclient