Click or drag to resize

PdfTimeStamperGetTimeStamp Method

An abstract method which will be called by RAD PDF to time stamp a certificate based signature created to certify the output PDF.

Namespace:  RadPdf.Integration
Assembly:  RadPdf (in RadPdf.dll) Version: 3.22.0.0 (3.22.0.0)
Syntax
public abstract byte[] GetTimeStamp(
	SignerInfo signer
)

Parameters

signer
Type: System.Security.Cryptography.PkcsSignerInfo
the SignerInfo used when signing the document, but before being embedded in the output PDF

Return Value

Type: Byte
the encoded, signed CMS object including the time stamp authority's certificate. The returned value will be added to the CMS/PKCS #7 message as its timestamp.
Remarks

Adobe Acrobat uses SHA256 as the digest (hash) algorithum for time stamping requests.

Examples

In this example, the open source library Bouncy Castle (https://www.bouncycastle.org/csharp/) and its classes TimeStampRequest and TimeStampResponse are used time stamp a signature.

C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography; // requires a project reference to System.Security
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
using System.Text; 

using Org.BouncyCastle.Math; //requires Bouncy Castle (https://www.bouncycastle.org/csharp/)
using Org.BouncyCastle.Tsp;

using RadPdf.Integration;

public class MyTimeStamper : PdfTimeStamper
{
    public override byte[] GetTimeStamp(SignerInfo signer)
    {
        byte[] digest;
        using (SHA256CryptoServiceProvider sha = new SHA256CryptoServiceProvider())
        {
            digest = sha.ComputeHash(signer.GetSignature());
        }

        TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
        reqGen.SetCertReq(true);

        TimeStampRequest tsReq = reqGen.Generate(TspAlgorithms.Sha256, digest, BigInteger.ValueOf(DateTime.UtcNow.Ticks));

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://timestamp.digicert.com");
        req.Method = "POST";
        req.ContentType = "application/timestamp-query";
        req.ContentLength = tsData.Length;

        byte[] reqData = tsReq.GetEncoded();
        Stream reqStream = req.GetRequestStream();
        reqStream.Write(reqData, 0, reqData.Length);
        reqStream.Close();

        byte[] resData;

        using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
        {
            using (MemoryStream ms = new MemoryStream())
            {
                Stream resStream = res.GetResponseStream();
                resStream.CopyTo(ms);
                resStream.Close();

                resData = ms.ToArray();
            }
        }

        TimeStampResponse tsRes = new TimeStampResponse(resRaw);

        tsRes.Validate(tsReq);

        return tsRes.TimeStampToken.ToCmsSignedData().GetEncoded();
    }
}

If using ASP.NET Core, the native classes Rfc3161TimestampRequest and Rfc3161TimestampToken can be used:

C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
using System.Text; 

using RadPdf.Integration;

public class MyTimeStamper : PdfTimeStamper
{
    public override byte[] GetTimeStamp(SignerInfo signer)
    {
        byte[] nonce = new byte[8];
        using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(nonce);
        }

        Rfc3161TimestampRequest request = Rfc3161TimestampRequest.CreateFromSignerInfo(
            signer, 
            HashAlgorithmName.SHA256,
            requestSignerCertificates: true, 
            nonce: nonce);

        byte[] tsData = request.Encode();

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://timestamp.digicert.com");
        req.Method = "POST";
        req.ContentType = "application/timestamp-query";
        req.ContentLength = tsData.Length;

        Stream reqStream = req.GetRequestStream();
        reqStream.Write(tsData, 0, tsData.Length);
        reqStream.Close();

        byte[] resRaw;

        using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
        {
            using (MemoryStream ms = new MemoryStream())
            {
                Stream resStream = res.GetResponseStream();
                resStream.CopyTo(ms);
                resStream.Close();

                resRaw = ms.ToArray();
            }
        }

        Rfc3161TimestampToken token = request.ProcessResponse(resRaw, out _);

        return token.AsSignedCms().Encode();
    }
}

Use a custom PdfIntegrationProvider implementation to use your time stamper when certifying a document:

C#
using System;
using System.Web;

using RadPdf.Integration;

public class CustomPdfIntegrationProvider : PdfIntegrationProvider
{
    public override void OnDocumentSaving(DocumentSavingEventArgs e)
    {
        base.OnDocumentSaving(e);

        e.CertifyUsing = new PdfCertifier(@"C:\path\to\cert.pfx", "password");
        e.CertifyUsing.TimeStampUsing = new MyTimeStamper();
    }
}
See Also