Click or drag to resize

PdfTimeStamper.GetTimeStamp 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: 4.2.0.0 (4.2.0.0)
Syntax
public abstract byte[] GetTimeStamp(
	SignerInfo signer
)

Parameters

signer
Type: System.Security.Cryptography.Pkcs.SignerInfo
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
This website uses cookies to identify your session and other necessary functions. By using this website, you are agreeing to our Terms of Use and Privacy Policy (updated April 26 2021).
Learn About Cookies
Got it!