前提:我有一个证书,我想验证系统‘信任’这个证书(由一个受信任的根CA由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:将Java的cacerts文件加载到keystore中,并检查每个“最受信任的”证书和我的证书是否相等。
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之间的解决方案?我觉得应该有一些类,我可以调用这些类来简单地验证证书的系统信任,而不必跳过几个圈。
发布于 2016-04-26 20:11:49
在阅读了David用Java编写的开始密码之后,我生成了下面的示例来验证证书链(这实现了使用系统信任库验证根CA的最初目标)
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", new BouncyCastleProvider());
InputStream is = new ByteArrayInputStream(some bytes in an array);
CertPath certPath = certificateFactory.generateCertPath(is, "PKCS7"); // Throws Certificate Exception when a cert path cannot be generated
CertPathValidator certPathValidator = CertPathValidator.getInstance("PKIX", new BouncyCastleProvider());
PKIXParameters parameters = new PKIXParameters(KeyTool.getCacertsKeyStore());
PKIXCertPathValidatorResult validatorResult = (PKIXCertPathValidatorResult) certPathValidator.validate(certPath, parameters); // This will throw a CertPathValidatorException if validation fails这也实现了不必使用SSL类的目标--而是使用Java安全类/算法。
发布于 2016-04-19 21:24:54
除非下载第三方库,否则可能没有其他选择。
为什么要避免使用"SSL“库?它是标准库的一部分,因此不会给您的程序带来负担。
无论如何,证书验证是SSL的一个重要部分。我怀疑没有人会在创建库时遇到麻烦,因为库的创建不需要实现SSL协议的一些实质性子集。只是没有真正的理由这么做。
https://stackoverflow.com/questions/36610312
复制相似问题