【问题标题】:Ignore SSLHandshakeException only for one particular Server仅针对一个特定服务器忽略 SSLHandshakeException
【发布时间】:2013-10-01 02:11:28
【问题描述】:

我需要忽略 PKIX 路径构建异常

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderExc
ption: unable to find valid certification path to requested target

我知道如何通过编写自己的实现 X509TrustManager 的类来做到这一点,我总是从 isServerTrusted 实现 return true

但这是相当广泛的。我的代码将成为更大项目的一部分。我不希望其他一切都因我更换信托经理而受到影响。

我总是会连接到一个固定的域名,即“www.myws.com”。我只想忽略 SSLHandshakeException 仅用于连接到“www.myws.com”。

这样的事情可能吗?

【问题讨论】:

  • 这与您的其他问题非常相似,但似乎更关注如何为特定连接设置信任管理器。您使用的是哪些库?
  • @Bruno 这与我的其他问题类似。但肯定不是重复的。从 2 个不同的角度解决相同的问题。当域名与证书中的主题不匹配时,会引发 SSL 异常。在这里我尝试根据域名进行过滤,我尝试根据主题进行过滤。两个问题的答案几乎不可能相同,因为我认为 TrustMananger 根本不会获得服务器的域名。我认为域名比较会在要求 TrustManager 验证证书是否由受信任的 CA 签名之前(或之后)发生。
  • 很公平。如果没有更多关于您对该客户端代码的控制程度以及正在使用哪些库的详细信息,几乎不可能回答您的问题。
  • 澄清一下,您不能“忽略 SSLHandshakeException”。这对连接是致命的。但你可以阻止它发生。

标签: java security ssl x509certificate pki


【解决方案1】:

两个问题的答案几乎不可能相同,因为我认为 TrustMananger 根本没有获取服务器的域名。

实际上,信任管理器可以获得您所追求的主机名的名称。不过,这取决于许多因素。

  • 假设您的客户端在 Java 7 上运行。

    如果您遵循与this other answer 相同的方法,但使用X509ExtendedTrustManager(Java 7 中引入,而不是普通的X509TrustManager),您将获得额外的重载方法,为您提供当前@987654327 @ 或 SSLEngine 也是如此。

    SSLContext 在使用X509ExtendedTrustManager 实例初始化时会使用这些方法,但在它是普通的X509TrustManager 时不会使用这些方法,因此它必须在进行这些调用之前检查类型(请参阅末尾的快速测试这个答案,基于the code in that answer)。

    我不确定这种行为是在 API 的何处指定的。 JSSE Reference Guide 中的 X509ExtendedTrustManager 类型检查似乎没有任何内容。 确保使用扩展方法的一种方法是设置enpoint identification algorithm (like HTTPS) in your SSLParameters,但您需要对客户端代码及其使用的库进行一定程度的控制。 (这也是 Java 7 中引入的一个特性。)

    从那里获得的SSLSocketSSLEngine 中,您可以获得SSLSession 和对等主机,因此您可以在那里进行检查。 (请注意,如果创建SSLSocketSSLEngine 的库没有使用将名称作为String 传递的方法之一,而是传递了InetAddress,则主机名可能与预期不完全匹配. 在这种情况下,您也会丢失 SNI。)

    然后,您可以在默认的SSLContext(使用setDefault(...))中使用这样的信任管理器。

  • 如果您不想影响默认的SSLContext(这种调整的明智选择),您需要弄清楚您的客户端库如何在每个连接中使用不同的库。这完全取决于使用的内容。

    对于传统的URLConnection,将其转换为HttpsURLConnection,并将SSLSocketFactory 设置为自定义SSLContext 的一个构建。


使用哪些方法取决于您是实例化了X509ExtendedTrustManager 还是X509TrustManager

X509TrustManager customTm = new X509ExtendedTrustManager() {
    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return finalTm.getAcceptedIssuers();
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain,
            String authType) throws CertificateException {
        System.out
                .println("Current method: checkServerTrusted(chain, authType)");
        finalTm.checkServerTrusted(chain, authType);
    }

    //@Override
    public void checkServerTrusted(X509Certificate[] chain,
            String authType, Socket socket) throws CertificateException {
        System.out
                .println("Current method: checkServerTrusted(chain, authType, socket)");
        finalTm.checkServerTrusted(chain, authType, socket);
    }

    //@Override
    public void checkServerTrusted(X509Certificate[] chain,
            String authType, SSLEngine engine)
            throws CertificateException {
        System.out
                .println("Current method: checkServerTrusted(chain, authType, engine)");
        finalTm.checkServerTrusted(chain, authType, engine);
    }

    // Same for client-related methods.
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2020-06-03
    相关资源
    最近更新 更多