This module uses the DevExpress PDF Document API to sign PDF documents. This demo uses the predefined sample.
Select the hash algorithm from the drop-down menu. The Signature Appearance Settings section allows you to specify signature's visual appearance options, such as appearance type, background, and signer information.
Click Sign Document to update the document and download the result.
Sample document and certificate
Sample_Alternative.pdf
Sample_Certificate.pfx
Signature Appearance Settings
using DevExpress.Pdf;
using DevExpress.Office.DigitalSignatures;
using DevExpress.Office.Tsp;
async Task<PdfSignatureAppearance> BuildSignatureAppearance(PdfSignatureAppearanceType signatureAppearanceType, string dateTimeFormat,
bool rightToLeftTextDirection, bool showDate, bool showDistinguishedName, bool showLabels, bool showLocation, bool showName,
bool showReason, Stream signatureBackgroundImageStream = null, Stream signatureImageStream = null) {
var appearance = new PdfSignatureAppearance() {
AppearanceType = signatureAppearanceType,
ApplicationVersion = "v1.0",
DateTimeFormat = dateTimeFormat,
RightToLeftTextDirection = rightToLeftTextDirection,
ShowDate = showDate,
ShowDistinguishedName = showDistinguishedName,
ShowLabels = showLabels,
ShowLocation = showLocation,
ShowName = showName,
ShowReason = showReason,
SignatureDetailsFont = new PdfSignatureFontSettings("Calibri"),
SignatureNameFont = new PdfSignatureFontSettings("Calibri")
};
if(signatureBackgroundImageStream != null)
appearance.SetBackgroundImageData(signatureBackgroundImageStream);
if(signatureAppearanceType == PdfSignatureAppearanceType.Image && signatureImageStream != null)
appearance.SetImageData(signatureImageStream);
return appearance;
}
async Task<PdfSignatureFieldInfo> CreateSignatureField(PdfDocumentProcessor processor) {
var page = processor.Document.Pages.Last();
var cropBox = page.CropBox;
var signatureFieldBounds = new PdfRectangle(
cropBox.Width / 3,
cropBox.Height / 10,
cropBox.Width / 3 * 2,
cropBox.Height / 10 * 2);
var signatureFieldInfo = new PdfSignatureFieldInfo(processor.Document.Pages.Count);
signatureFieldInfo.Name = "SignatureField";
signatureFieldInfo.SignatureBounds = signatureFieldBounds;
return signatureFieldInfo;
}
async Task<MemoryStream> Sign(Stream documentStream, Stream certificateStream, Stream signatureImageStream,
HashAlgorithmType certificateHashAlgorithm, HashAlgorithmType tsaHashAlgorithm, PdfSignatureAppearance signatureAppearance = null) {
using var processor = new PdfDocumentProcessor();
processor.LoadDocument(documentStream);
var signatureFieldInfo = await CreateSignatureField(processor);
using var documentSigner = new PdfDocumentSigner(documentStream);
var tsaClient = new TsaClient(
new Uri("https://www.freetsa.org/tsr", UriKind.Absolute),
tsaHashAlgorithm);
var pkcs7Signer = new Pkcs7Signer(certificateStream, "dxdemo", certificateHashAlgorithm, tsaClient);
var signatureBuilder = new PdfSignatureBuilder(pkcs7Signer, signatureFieldInfo) {
ApplicationName = "DevExpress Office File API Demo",
CertificationLevel = PdfCertificationLevel.NoCertification,
ContactInfo = "support@devexpress.com",
Location = "Area 51",
Name = "John Doe",
Reason = "Demo",
SigningTime = DateTime.UtcNow
};
if(signatureAppearance != null)
signatureBuilder.SetSignatureAppearance(signatureAppearance);
else if(signatureImageStream != null)
signatureBuilder.SetImageData(signatureImageStream);
var outputStream = new MemoryStream();
documentSigner.SaveDocument(outputStream, signatureBuilder);
outputStream.Position = 0;
return outputStream;
}