问题
I have a document that is digitally signed using CAdES. I use BouncyCastle APIs to get the X509Certificate[]
instances of the signers, but let's assume the list contains one and one only element.
I need to verify whether this certificate is trusted or not at today's date, and I don't want to use the system's standard trust store which is normally used to trust SSL certificates. No, I want to build my own trust list with a list of .cer
files in my classpath. At the moment, a single CA is trusted but obviously in the future a few more certificates may be added.
So far I have read this and tried to implement in my code. I need no SSLContext
, I need to check the validity of a digitally signed document. I am now confused.
X509TrustManager
APIs do however provide only methods for validating client/server certificates, but mine only have digital signature/non-repudiation usage flags.
The questions can be formulated in two ways that lead to the same:
- How does one in Java check the validity of an
X509Certificate
instance against a custom root CA list that can be loaded in memory? - How does one check that a digitally-signed document is signed with a certificate deriving from a known CA of a custom list?
回答1:
Extract from the CAdES signature for each signer the signer's certificate and also the intermediate certificates as a X509Certificate
list. Build also a set with all root CA certificates
Then you can use this (slightly adapted) example code to verify and build the certification chain using Java and BouncyCastle. It will return the certification chain if verification is successful
public PKIXCertPathBuilderResult verifyCertificateChain(
X509Certificate cert,
Set<X509Certificate> trustedRootCerts,
Set<X509Certificate> intermediateCerts) throws GeneralSecurityException {
// Create the selector that specifies the starting certificate
X509CertSelector selector = new X509CertSelector();
selector.setCertificate(cert);
// Create the trust anchors (set of root CA certificates)
Set<TrustAnchor> trustAnchors = new HashSet<TrustAnchor>();
for (X509Certificate trustedRootCert : trustedRootCerts) {
trustAnchors.add(new TrustAnchor(trustedRootCert, null));
}
// Configure the PKIX certificate builder algorithm parameters
PKIXBuilderParameters pkixParams =
new PKIXBuilderParameters(trustAnchors, selector);
// Disable CRL checks (this is done manually as additional step)
pkixParams.setRevocationEnabled(false);
// Specify a list of intermediate certificates
// certificate itself has to be added to the list
intermediateCerts.add(cert);
CertStore intermediateCertStore = CertStore.getInstance("Collection",
new CollectionCertStoreParameters(intermediateCerts), "BC");
pkixParams.addCertStore(intermediateCertStore);
// Build and verify the certification chain
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC");
PKIXCertPathBuilderResult result =
(PKIXCertPathBuilderResult) builder.build(pkixParams);
return result;
}
If you do not want to deal with CAdES complexity, I suggest to use SD-DSS open-source project
来源:https://stackoverflow.com/questions/42527241/check-a-certificate-validity-against-a-custom-trust-list-in-java