信任不受信任的证书并跳过主机名验证

时间:2015-04-09 19:03:44

标签: java ssl

我有一台运行https网络服务器的服务器。当我用我的浏览器输入它时,我得到域不匹配的错误(因为我使用服务器的IP)并且证书不受信任。 现在我需要使用apache httpclient 4.2.1向该服务器发送GET请求。我在网上发现了一段代码,可以帮助我:

    httpClient = new DefaultHttpClient(a, b);
    SSLSocketFactory sslSocketFactory = new SSLSocketFactory(
            new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                    return true;
                }
            }, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, sslSocketFactory));

因为我不完全理解这段代码,所以我想问一些问题。

1)我是否理解SSlSocetFactory的第一个参数是绕过证书问题的“不可信”部分?它基本上只返回每个证书都是可信的吗?

2)可能需要第二个参数,因为我的证书主机名没有加载URL?

3)这个SchemeRegistry和Scheme究竟是什么?我正在使用参数“https”,443和我之前创建的SSLSocketFactory创建一个新的Scheme。我知道这个方案适用于https连接,它使用我在sslSocketFactory中定义的规则但是端口是什么?这是否适用于仅在端口443或其他端口上的https连接?如果我的端口不同,我应该输入不同的端口吗?

4)最重要的问题:如果我使用可信证书,那我怎么能跳过主机名验证而不改变信任策略?

1 个答案:

答案 0 :(得分:1)

  

1)我是否理解SSlSocetFactory的第一个参数是绕过证书问题的“不可信”部分?它基本上只返回每个证书都是可信的吗?

是。这是一个非常糟糕的主意。

  

2)可能需要第二个参数,因为我的证书主机名没有加载URL?

是。这也是一个非常糟糕的主意。

  

...但是

的端口是什么

这是协议的默认端口,即如果您提供https://host/ URL而不是https://host:port/,则知道该端口将为443。

  

4)最重要的问题:如果我使用可信证书,那我怎么能跳过主机名验证而不改变信任策略?

禁用验证的这一重要部分将是一个非常糟糕的主意。实际上,您将允许使用由受信任CA签署的任何证书,而不是您自己的证书。由于很容易拥有某个域并获得可靠的证书,因此您可以轻松实现中间人攻击。

如果真的不可能使用正确的证书(为什么你还使用IP而不是名字?)那么你应该使用证书或公钥固定来仅信任这个证书。有关详细信息,请参阅OWASP