Предпосылка: у меня есть сертификат, и я хочу убедиться, что система "доверяет" этому сертификату (подписанному доверенным корневым ЦС с помощью Java/операционной системы)
Я нашел несколько различных решений о том, как это сделать.
Опция 1:
Используйте классы SSL для получения доверия.
TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmfactory.init((KeyStore) null);
for (TrustManager trustManager : tmfactory.getTrustManagers()) {
if (trustManager instanceof X509TrustManager) {
try {
((X509TrustManager) trustManager).checkClientTrusted(new X509Certificate[] {new JcaX509CertificateConverter().getCertificate(holder)}, "RSA");
System.out.println("This certificate is trusted by a Root CA");
} catch (CertificateException e) {
e.printStackTrace();
}
}
}
Поскольку этот подход сильно зависит от классов SSL (которые не нужны текущему проекту), мы ищем альтернативы.
Вариант 2. Загрузите файл cacerts
file Java в хранилище ключей и проверьте соответствие каждого «наиболее надежного» сертификата моему сертификату.
String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar);
FileInputStream is = new FileInputStream(filename);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
String password = "changeit";
keystore.load(is, password.toCharArray());
// This class retrieves the most-trusted CAs from the keystore
PKIXParameters params = new PKIXParameters(keystore);
// Get the set of trust anchors, which contain the most-trusted CA certificates
Set<X509Certificate> rootCertificates = params.getTrustAnchors().parallelStream().map(TrustAnchor::getTrustedCert).collect(Collectors.toSet());
return rootCertificates.contains(holderX509);
Проблема с этим подходом заключается в том, что для проверки целостности файла, закодированного JKS, требуется пароль. В то время как SSL, по-видимому, не использует (или, скорее, использует System.getProperty("javax.net.ssl.trustStorePassword")
, который снова сильно привязан к SSL.
Вопрос. Существует ли промежуточное решение между ручной загрузкой сертификатов из файла и чистым SSL? Я чувствую, что должен быть какой-то класс, который я могу вызвать, чтобы просто проверить доверие системы к сертификату без необходимости прыгать через пару обручей.