gpt4 book ai didi

java - 实现 X509TrustManager - 将部分验证传递给现有的验证者

转载 作者:太空狗 更新时间:2023-10-29 23:00:44 30 4
gpt4 key购买 nike

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

但是,我不想信任所有服务器和所有客户端。

  • 我希望像目前一样为客户完成所有默认验证。
  • 对于服务器,我只想忽略一个特定证书的服务器证书验证,但想继续并像当前所做的那样验证它(例如,使用 cacerts 存储)。

我怎样才能实现这样的目标 - 即在替换之前将部分验证传递给 X509TrustFactory 对象。

即这就是我想要做的

public boolean isServerTrusted(X509Certificate[] chain)
{
if(chain[0].getIssuerDN().getName().equals("MyTrustedServer") && chain[0].getSubjectDN().getName().equals("MyTrustedServer"))
return true;

// else I want to do whatever verification is normally done
}

另外,我不想打扰现有的 isClientTrusted 验证。

我该怎么做?

最佳答案

您可以获取现有的默认信任管理器并使用如下方式将其包装在您自己的信任管理器中:

TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
// Using null here initialises the TMF with the default trust store.
tmf.init((KeyStore) null);

// Get hold of the default trust manager
X509TrustManager x509Tm = null;
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
x509Tm = (X509TrustManager) tm;
break;
}
}

// Wrap it in your own class.
final X509TrustManager finalTm = x509Tm;
X509TrustManager customTm = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return finalTm.getAcceptedIssuers();
}

@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
finalTm.checkServerTrusted(chain, authType);
}

@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
finalTm.checkClientTrusted(chain, authType);
}
};

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { customTm }, null);

// You don't have to set this as the default context,
// it depends on the library you're using.
SSLContext.setDefault(sslContext);

然后您可以围绕 finalTm.checkServerTrusted(chain, authType); 实现您自己的逻辑。

但是,您应该确保为要忽略的特定证书设置异常(exception)。

您在下面所做的是让具有这些颁发者 DN 和主题 DN(不难伪造)的任何证书通过:

if(chain[0].getIssuerDN().getName().equals("MyTrustedServer") && chain[0].getSubjectDN().getName().equals("MyTrustedServer"))
return true;

您可以改为从已知引用加载 X509Certificate 实例并比较链中的实际值。

此外,checkClientTrustedcheckServerTrusted 不是返回truefalse 的方法,而是 void 默认情况下会成功的方法。如果您期望的证书有问题,请显式抛出 CertificateException

关于java - 实现 X509TrustManager - 将部分验证传递给现有的验证者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19005318/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com