我见过很多构造一个将接受所有服务器证书的 SSLContext
的例子。对于我的测试用例,我试图做完全相反的事情并强制客户端拒绝服务器的证书。
所以我正在尝试创建一个不包含根证书的 KeyStore
对象,但是当我尝试使用它时,我得到一个 InvalidAlgorithmParameterException
消息 'the trustAnchors参数必须是非空的'。我试过这个:
KeyStore emptyTrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
emptyTrustStore.load(null, null);
sslcontext = SSLContexts.custom().loadTrustMaterial(emptyTrustStore, new TrustNoOneStrategy()).build();
还有这个:
KeyStore emptyTrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
emptyTrustStore.setCertificateEntry("notreal", null);
sslcontext = SSLContexts.custom().loadTrustMaterial(emptyTrustStore, new TrustNoOneStrategy()).build();
和(来自评论中的一个想法):
KeyStore emptyTrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustNoOneStrategy()).build();
但是这些方法都没有解决问题。
显然,我可以简单地创建一个包含虚拟根证书的 JKS 文件,并使用 SSLContexts.loadTrustMaterial(File)
方法加载它,但这看起来真的很丑陋:肯定有一种方法可以做到这只是在代码中?
最佳答案
试试这个:
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {
throw new CertificateException();
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}}, null);
请注意,信任管理器将为每个质询抛出异常。
您可以看到拒绝糟糕的 stackoverflow 证书的上下文:
HttpsURLConnection connection =
(HttpsURLConnection)
new URL("https://stackoverflow.com/").openConnection();
connection.setSSLSocketFactory(sslContext.getSocketFactory());
connection.getResponseCode();
关于java - 如何创建不信任任何服务器证书的 SSLContext?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43668659/