I'm trying to do the following setup for signing pdfs, broken down into asynchronous steps between a client and a server:
- A server receives a pdf and computes it's digest.
- Server sends the digest to a client.
- Client signs the hash at a later time.
- Client sends the signature to server.
- Server embeds the signature into the pdf.
I'm basing myself mainly in PDF Signature digest and Create pkcs7 signature from file digest
The second question allowed me to write most of the code, however I'm getting that the integrity of the file has been compromised. I can't seem to serialize the intermediary pdf for embedding the signature later (to make sure no timestamps are altered, etc). But from the first SO question, it seems to be a harder problem than I thought. Can it actually be done?
I'm using pdfbox.
Server code:
PDDocument document = PDDocument.load(documentFile);
PDSignature signature = new PDSignature();
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signature.setName("Example User");
signature.setLocation("Los Angeles, CA");
signature.setReason("Testing");
Calendar date = Calendar.getInstance();
signature.setSignDate(date);
document.addSignature(signature);
ExternalSigningSupport externalSigningSupport = document.saveIncrementalForExternalSigning(null);
byte[] content = IOUtils.toByteArray(externalSigningSupport.getContent());
MessageDigest md = MessageDigest.getInstance("SHA256", new BouncyCastleProvider());
byte[] digest = md.digest(content); // this is sent to client
What I'm basically doing is sending that digest to the client to sign and then on the server redoing the above steps and setting the client signature:
ExternalSigningSupport externalSigning = document.saveIncrementalForExternalSigning(fos);
externalSigning.setSignature(encodedSignature); // encodedSignature is received from client and computed based on the digest sent by the server
This setup ends up with the integrity of the file being corrupted, since I'm creating a new PDSignature once I have the encodedSignature
on the server to embed it. Is there a way to serialize the PDDocument created after calling addSignature, so I can later deserialize it on the server and add the client's signature?