我正在尝试使用 Java从用户证书和 CA 证书CertPathBuilder
创建,但我收到CertPath
Exception in thread "main" sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at CertPathBuilderTest.main(CertPathBuilderTest.java:63)
当我启用了吊销检查(使用.setRevocationEnabled(true)
)。所以看起来 Java 拒绝证书或 CRL,即使我可以使用 OpenSSL 和 gnupg 毫无问题地验证它们。
CA 结构是最简单的:只有 CA 签名证书和 CRL,没有中间 CA。
有问题的证书:cacerts.jks和private.jks
示例程序:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CRL;
import java.security.cert.CRLException;
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertPathBuilderResult;
import java.security.cert.CertStore;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.X509CRL;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
public class CertPathBuilderTest {
/**
* @param args
* @throws IOException
* @throws CertificateException
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws CRLException
* @throws InvalidAlgorithmParameterException
* @throws UnexpectedJCAException
* @throws SigningCertChainException
* @throws CertPathBuilderException
*/
public static void main(String[] args)
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, CRLException, InvalidAlgorithmParameterException, CertPathBuilderException
{
// TODO Auto-generated method stub
// keytool -importcert -file CA.pem -keystore cacerts.jks -storepass changeit
KeyStore trustAnchors = loadJKSKeyStore("cacerts.jks", "changeit");
KeyStore myKeyStore = loadJKSKeyStore("private.jks", "changeit");
String crlLocation = "http://crl.qbs.com.pl/QBSJanKuban.crl";
X509CRL crl = downloadCRL(crlLocation);
CertStore cs = otherCertificatesCertStore(trustAnchors, myKeyStore, crl);
///*
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
X509CertSelector certSelector = new X509CertSelector();
certSelector.setCertificate((X509Certificate) myKeyStore.getCertificate("mykey"));
PKIXBuilderParameters cpp = new PKIXBuilderParameters(trustAnchors, certSelector);
cpp.addCertStore(cs);
cpp.setRevocationEnabled(true);
cpp.setMaxPathLength(6);
cpp.setDate(new Date());
CertPathBuilderResult a = cpb.build(cpp);
CertPath certPath = a.getCertPath();
}
private static KeyStore loadJKSKeyStore(String path, String password)
throws KeyStoreException,
NoSuchAlgorithmException, CertificateException, IOException
{
FileInputStream fis = new FileInputStream(path);
KeyStore ks = KeyStore.getInstance("jks");
ks.load(fis, password.toCharArray());
fis.close();
return ks;
}
private static X509CRL downloadCRL(String crlLocation)
throws IOException, CertificateException, CRLException
{
URL crlURL = new URL(crlLocation);
BufferedInputStream in = new BufferedInputStream(crlURL.openStream());
CertificateFactory cf = CertificateFactory.getInstance("X.509");
CRL crl = cf.generateCRL(in);
return (X509CRL) crl;
}
private static CertStore otherCertificatesCertStore(KeyStore trustAnchors,
KeyStore myCerts, X509CRL... crl)
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, KeyStoreException
{
CertStore cs;
Collection<Object> contentList = new ArrayList<Object>();
contentList.add(trustAnchors.getCertificate("qbsca"));
contentList.add(myCerts.getCertificate("mykey"));
for (int i=0; i < crl.length; i++) {
contentList.add(crl[i]);
}
cs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(contentList));
return cs;
}
}