PDF签名中pdfRevocationInfoArchival OID属性相关问题及验证工具问询
Let's break down your questions one by one, and verify against the Adobe specs and your code implementation:
1. Validity of the adbe-revocationInfoArchival OID and verification capability
The OID you're using (1.2.840.113583.1.1.8) is exactly the correct identifier for Adobe's adbe-revocationInfoArchival attribute, as defined in the Adobe PDF Security specifications.
PDF validation tools that adhere to Adobe's signature standards (like Adobe Acrobat, iText, PDFBox, etc.) will recognize this OID and use the embedded CRL data to perform revocation checks during signature verification. As long as the attribute's structure is correct (we'll cover that next), the PDF should be verifiable via this OID.
2. Compliance of the attribute format with PDF requirements
Looking at your code and the ASN.1 definition provided:
RevocationInfoArchival ::= SEQUENCE { crl [0] EXPLICIT SEQUENCE of CRLs, OPTIONAL ocsp [1] EXPLICIT SEQUENCE of OCSP Responses, OPTIONAL otherRevInfo [2] EXPLICIT SEQUENCE of OtherRevInfo, OPTIONAL }
Your implementation correctly follows this structure:
- You're creating an
ASN1EncodableVector(v1) to hold the components of theRevocationInfoArchivalsequence. - For the CRLs, you wrap the sequence of DER-encoded CRLs in an EXPLICIT tagged object (using
DERTaggedObject(true, 0, ...)— thetrueflag denotes EXPLICIT tagging, which matches the spec's[0] EXPLICITrequirement). - You then wrap this tagged object in a
DERSequenceto form the completeRevocationInfoArchivalvalue, and place it inside aDERSetfor the CMS Attribute (which is required because CMS Attribute values are defined asSET OF AttributeValue).
One minor note: Ensure that the CRLs you're embedding are properly DER-encoded (your code uses X509CRL.getEncoded() which is correct) and that they correspond to the signer's certificate chain.
3. Tools to verify and visualize the signature attribute
Here are reliable tools to check your implementation:
- Adobe Acrobat: Open the signed PDF, go to the signature panel, right-click the signature → Properties → Show Signer's Certificate → Revocation tab. It will show if the embedded CRL was used for validation, and whether the revocation check passed.
- iText RUPS: A GUI tool for inspecting PDF internals. You can navigate to the signature's CMS container, locate the signed attributes, and view the ASN.1 structure of the
adbe-revocationInfoArchivalattribute directly. - Bouncy Castle CMS Utilities: Use the
org.bouncycastle.cmsclasses to parse the CMS signed data programmatically. You can extract the signed attributes, find the one matching the OID, and print its ASN.1 structure. - OpenSSL: Extract the CMS signature from the PDF (you can use tools like PDFBox to get the signature bytes), then run:
This will display all signed attributes, including the revocation info.openssl cms -verify -in signature.der -inform der -noverify -print - Apache PDFBox: Write a small Java program to load the PDF, extract the signature, and inspect the
adbe-revocationInfoArchivalattribute using PDFBox's signature APIs.
4. Correctness of placing issuer CRL in position [0]
Yes, this is 100% correct. The ASN.1 definition explicitly maps the crl field to the tag number 0 with EXPLICIT tagging. By using DERTaggedObject(true, 0, ...) for your CRL sequence, you're exactly following the specification. This is the standard place to embed CRLs for Adobe PDF signature revocation checks.
Minor Code Improvement
Don't forget to close your input streams (ASN1InputStream t and FileInputStream) to avoid resource leaks. You can use try-with-resources in Java to handle this automatically:
try (CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); FileInputStream fis = new FileInputStream(new File("e://app//esp//crl//NSDLe-GovCA2019-Test-2.crl"))) { CRL crl = certFactory.generateCRL(fis); crls.add((X509CRL)crl); if (!crls.isEmpty()) { ASN1EncodableVector v11 = new ASN1EncodableVector(); for (X509CRL crlItem : crls) { try (ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(crlItem.getEncoded()))) { v11.add(t.readObject()); } } v1.add(new DERTaggedObject(true, 0, new DERSequence(v11))); } } catch (Exception e) { // Handle exceptions appropriately }
内容的提问来源于stack exchange,提问作者Nikhil Wankhade

