Reputation: 322
I am currently working on an outdated project which signs PDF/A and tried to upgrade its dependencies. The relevant one here is co.lowagie.itext which I upgraded from 1.4 to 5.5.13.1. A lot has changed because the function PdfSignatureAppearance.setCrypto()
was removed. I implemented the fix in this (I implemented the required jars in the newest version) question and am now got this code:
PdfStamper stp;
try {
stp = PdfStamper.createSignature(reader, fout, '\0');
PdfSignatureAppearance sap = stp.getSignatureAppearance();
ExternalDigest digest = new BouncyCastleDigest();
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
ExternalSignature signature = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA256, provider.getName());
MakeSignature.signDetached(sap, digest, signature, certificateChain, null, null, null, 0, MakeSignature.CryptoStandard.CMS);
stp.close();
}
For comparison here is the old code:
PdfStamper stp;
try {
stp = PdfStamper.createSignature(reader, fout, '\0');
PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setCrypto(privateKey, certificateChain, null, PdfSignatureAppearance.WINCER_SIGNED);
stp.close();
}
Here is where my problem comes up. During testing I noticed that this new version, turns the PDF/A to PDF1.4 which the older version didn't do. I am not experienced with PDF or PDF signing.
Upvotes: 0
Views: 638
Reputation: 322
There where 2 problems hindering the code to create valid PDF/A
The first problem was, that I didn't use the PdfAStamper
class which is needed to stamp a PDF/A and retain its PDF/A validity.
The second problem was, that signed PDF/A need a signature where the timestamp is set by an external tsa server.
PdfStamper stp;
try {
stp = PdfAStamper.createSignature(reader, fout, '\0', PdfAConformanceLevel.PDF_A_1A); //<-- PdfAStamper with the PdfAConformanceLevel.
TSAClient tsaClient = new TSAClientBouncyCastle("https://freetsa.org/tsr"); //<-- creating the TSAClient
PdfSignatureAppearance sap = stp.getSignatureAppearance();
ExternalDigest digest = new BouncyCastleDigest();
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
ExternalSignature signature = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA256, provider.getName());
MakeSignature.signDetached(sap, digest, signature, certificateChain, null, null, tsaClient, 0, MakeSignature.CryptoStandard.CMS); //<-- Notice "tsaClient"
stp.close();
}
Upvotes: 0
Reputation: 95898
PDF/A-1 is a profile of PDF-1.4. So if your source PDF was PDF/A-1, it also was PDF-1.4 to start with and iText didn't change it so.
Furthermore, neither the old iText 1.4 nor the newer iText 5.5.13 PdfStamper
are PDF/A-aware. Quite likely your test checking the profile of your PDFs signed by iText 1.4 simply didn't recognize this.
In case of iText 5.5.13, though, you may have luck because in that version iText also provides a PdfAStamper
which is PDF/A-aware (this class is in a separate jar, though, itext-pdfa.jar).
Thus, please try again using the PdfAStamper
instead of the PdfStamper
. If that still doesn't help, please share an example PDF/A file representative for your input PDFs before and after signing using both the new and the old iText version. And also mention which program you use to determine whether a PDF is a PDF/A or not...
Upvotes: 1