Hello,
I am trying to implement a timestamp into a PDF signature created through a deferred signing process, but the timestamp data seems to be lost in the 2-step (deferred) process.
Please refer to the Ticket at https://www.syncfusion.com/forums/160161/prepare-pdf-hash-to-be-signed-and-sign-externally-with-smart-card-not-on-the-same-system for more information on the implementation.
In essence, the empty signature is prepared, and the PDF is saved. The bytes for signing are retrieved from the client-side, and the client signs it. The client posts the signature to the back-end, where we replace the empty one using PdfSignature.ReplaceEmptySignature (Syncfusion.Pdf.Security in assembly Syncfusion.Pdf.Portable).
Upon successfully signing the PDF document, the signature is there, and it is valid. However, it does not contain any timestamp data whatsoever.
The single line used for adding the timestamp (with actual URL):
signature.TimeStampServer = new TimeStampServer(new Uri("http://syncfusion.digistamp.com"), "user", "123456");
For reference, I have checked the validity of the timestamp server used. I can successfully add the timestamp if I do it on a document directly – code from the example at https://help.syncfusion.com/file-formats/pdf/working-with-digitalsignature#adding-a-timestamp-to-pdf-document. It does show the timestamp as a valid signature.
I suspect that the timestamp is added to the signature but maybe gets lost in the process when using PdfSignature.ReplaceEmptySignature.
Please let me know if deferred signing of PDF supports adding a timestamp in the signature, and how we can achieve this.
Best regards,
Marko
|
public byte[] Sign(byte[] message, out byte[] timeStampResponse)
{
byte[] signedBytes = _signedHash;
timeStampResponse = TimeStamp(message);
return signedBytes;
}
public byte[] TimeStamp(byte [] data)
{
SHA1 sha1 = SHA1CryptoServiceProvider.Create();
byte[] hash = sha1.ComputeHash(data);
TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
reqGen.SetCertReq(true);
TimeStampRequest tsReq = reqGen.Generate(TspAlgorithms.Sha1, hash, BigInteger.ValueOf(100));
byte[] tsData = tsReq.GetEncoded();
HttpWebRequest req =(HttpWebRequest)WebRequest.Create("http://syncfusion.digistamp.com"); // Update your timestamp Uri here
req.Method = "POST";
req.ContentType = "application/timestamp-query";
req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("9024:yourPass")));
req.ContentLength = tsData.Length;
Stream reqStream = req.GetRequestStream();
reqStream.Write(tsData, 0, tsData.Length);
reqStream.Close();
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
if (res != null)
{
Stream resStream = new BufferedStream(res.GetResponseStream());
TimeStampResponse tsRes = new TimeStampResponse(resStream);
return tsRes.TimeStampToken.GetEncoded();
}
return null;
} |
Hello,
The timestamp part of our signing process was put on hold last year, and now we're back to finishing the implementation.
We successfully used the provided code example and were able to call our preferred TSA, and the timestamp gets added to the document.
However, when checking the validity of the signature (in Adobe), we see the following:
The signature includes an embedded timestamp but it could not be verified.
And more specifically, inside the advanced signature properties, we see the following for the timestamp:
Timestamp Authority: Not available
and
There is no policy identified for this timestamp, or the policy could not be determined because the timestamp was not processed.
Is there any missing part in the code that would appropriately set up the timestamp data in the signature so that it can be verified?
Another thing I've been wondering is if the certificate chain is properly added from the TSA response, or do I have to do it manually (read in specifications of timestamping in PDF that it's required for validation)?
It does not seem so from the provided code, though, as all that is returned from the Timestamp(btye[] data) method is byte[] which in turn is the encoded TimeStampToken:
return tsRes.TimeStampToken.GetEncoded()
I appreciate your help.
Best regards,
Marko
Hi Marko,
We requested you to update the below-highlighted changes on your end to overcome the problem. We have attached the updated sample for your reference,
Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/Sample_TS1647950674.zip
Output: https://www.syncfusion.com/downloads/support/directtrac/general/pd/DeferredSign1355991356.pdf
|
public byte[] Sign(byte[] message, out byte[] timeStampResponse) { //Set the signed hash message to replace an empty signature. byte[] signedBytes = _signedHash; timeStampResponse = TimeStamp(signedBytes); return signedBytes; } public byte[] TimeStamp(byte[] data) { SHA1 sha1 = SHA1CryptoServiceProvider.Create(); byte[] hash = sha1.ComputeHash(data);
TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); reqGen.SetCertReq(true);
TimeStampRequest tsReq = reqGen.Generate(TspAlgorithms.Sha1, hash, BigInteger.ValueOf(100)); byte[] tsData = tsReq.GetEncoded(); HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://time.certum.pl"); // Update your timestamp Uri here req.Method = "POST"; req.ContentType = "application/timestamp-query"; req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("9024:yourPass"))); req.ContentLength = tsData.Length;
Stream reqStream = req.GetRequestStream(); reqStream.Write(tsData, 0, tsData.Length); reqStream.Close();
HttpWebResponse res = (HttpWebResponse)req.GetResponse(); if (res != null) { Stream resStream = new BufferedStream(res.GetResponseStream()); TimeStampResponse tsRes = new TimeStampResponse(resStream); return tsRes.TimeStampToken.GetEncoded(); } return null; } |
|
|
|
Please let us know if you need any further assistance in this.
Regards,
Gowthamraj K
Hi Gowthamraj,
I can't believe I haven't noticed/tried that before. That's the solution!
Thank you very much for the help.
I can confirm that this process of timestamping in the deferred signing process of PDF, does indeed, work.
Best regards,
Marko
Hi Marko,
We are glad that the provided details resolved the issue on your end. Kindly let us know if you need any assistance in this.
Regards,
Irfana J.