Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 仅对一个特定服务器忽略SSLHandshakeException_Java_Security_Ssl_X509certificate_Pki - Fatal编程技术网

Java 仅对一个特定服务器忽略SSLHandshakeException

Java 仅对一个特定服务器忽略SSLHandshakeException,java,security,ssl,x509certificate,pki,Java,Security,Ssl,X509certificate,Pki,我需要忽略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 我知道如何通

我需要忽略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
返回true

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

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

这样的事情可能吗

这两个问题的答案几乎不可能是相同的,因为我认为信任管理者根本无法获得服务器的域名

实际上,信任管理器可以获取您要查找的主机名的名称。但这取决于许多因素

  • 让我们假设您的客户机运行在Java7上

    如果使用与中相同的方法,但使用
    X509ExtendedTrustManager
    (在Java 7中引入,而不是普通的
    X509TrustManager
    ),您将获得额外的重载方法,这些方法也为您提供了当前的
    SSLSocket
    SSLEngine

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

    我不确定API在哪里指定了这种行为。中的
    X509ExtendedTrustManager
    类型检查似乎没有任何内容。 确保使用扩展方法的一种方法是设置,但您需要对客户端代码及其使用的库进行一定程度的控制。(这也是Java 7中引入的一项功能。)

    从那里获得的
    SSLSocket
    SSLEngine
    中,您可以获得
    SSLSession
    和对等主机,以便在那里执行检查。(请注意,如果创建
    SSLSocket
    SSLEngine
    的库没有使用将该名称作为
    字符串传递的方法之一,而是传递了
    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.
};

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