Adding a timestamp in the digital signature in deferred signing of PDF

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


6 Replies 1 reply marked as answer

GK Gowthamraj Kumar Syncfusion Team August 27, 2021 03:20 PM UTC

Hi Marko, 
 
Thank you for contacting Syncfusion support. 
 
Currently, we are checking with timestamp in the deferred signed on our end and we will update the further details on August 31st 2021.

 
Regards, 
Gowthamraj K 



MK Moorthy Karunanithi Syncfusion Team August 31, 2021 01:58 PM UTC

Hi Marko, 
 
Thank you for your patience,  
 
We can add a timestamp in the deferred signing by providing a timestamp response externally while signing the document. As a workaround, we have created a timestamp response from timestamp server Uri using BouncyCastle for your reference.  
 
        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; 
        } 
 
Please let us know if you need any further assistance in this. 
 
Regards, 
Moorthy K 



MB Marko Bezjak May 18, 2022 06:59 PM UTC

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



GK Gowthamraj Kumar Syncfusion Team May 19, 2022 12:24 PM UTC

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


Marked as answer

MB Marko Bezjak May 19, 2022 04:28 PM UTC

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




IJ Irfana Jaffer Sadhik Syncfusion Team May 20, 2022 12:44 PM UTC

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.


Loader.
Up arrow icon