Java 仅对一个特定服务器忽略SSLHandshakeException
我需要忽略PKIX路径构建异常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 我知道如何通
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上
如果使用与中相同的方法,但使用
(在Java 7中引入,而不是普通的X509ExtendedTrustManager
),您将获得额外的重载方法,这些方法也为您提供了当前的X509TrustManager
或SSLSocket
当使用SSLEngine
实例初始化时,X509ExtendedTrustManager
会使用这些方法,但当它是普通的SSLContext
时则不会,因此在进行这些调用之前,它必须检查类型(请参阅本答案末尾的快速测试,基于) 我不确定API在哪里指定了这种行为。中的X509TrustManager
类型检查似乎没有任何内容。 确保使用扩展方法的一种方法是设置,但您需要对客户端代码及其使用的库进行一定程度的控制。(这也是Java 7中引入的一项功能。) 从那里获得的X509ExtendedTrustManager
或SSLSocket
中,您可以获得SSLEngine
和对等主机,以便在那里执行检查。(请注意,如果创建SSLSession
或SSLSocket
的库没有使用将该名称作为SSLEngine
字符串传递的方法之一,而是传递了
,则主机名可能与预期不完全匹配。在这种情况下,您还将丢失SNI。) 然后,您可以在默认的InetAddress
(使用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”。这对连接是致命的。但是你可以阻止它发生。