Multiple Digital Signing with PdfStreamSigner
| Minimum Version | Q2 2025 |
|---|
RadPdfProcessing offers the PdfStreamSigner class. The SignDocument method it exposes allows the user to insert one or more Digital Signatures into a PDF document.
When adding multiple signatures, make sure the document is exported after each signature before importing it back again.
| Method | Description |
|---|---|
| PdfStreamSigner(Stream outputStream) | Creates a new instance of the PdfStreamSigner and specifies the output stream where the signed document will be written. |
| SignDocument(Stream originalStream, SignatureField signatureField, int pageIndex, TimeSpan? timeout) | Adds a Digital Signature to the PDF document |
As of Q1 2026 the PdfStreamSigner provides support for the TimeStamp server. Hence, the SignatureField used for signing the document preserves all of its SignatureSettings including the TimeStampServer.
The following example shows how to insert multiple Digital Signatures into a PDF document using the PdfStreamSigner:
In .NET Standard use Telerik.Documents.Primitives.Rect instead of System.Windows.Rect.
public void AddMultipleDigitalSignatures()
{
string certificateFilePath = "certificate.pfx";
string certificateFilePassword = "password";
// Define the certificate which will be used for the signing.
X509Certificate2 certificate = new X509Certificate2(certificateFilePath, certificateFilePassword);
// Create the first signature field.
SignatureField signature1Field = this.CreateSignatureField(
"SampleSignature1",
certificate,
new Point(50, 50),
20,
new Rect(200, 200, 100, 100)
);
string inputDocument = "input.pdf";
string oneSignatureDocument = "oneSignatureDocument.pdf";
File.Delete(oneSignatureDocument);
using (FileStream inputStream = File.OpenRead(inputDocument))
{
using (FileStream outputStream = new FileStream(oneSignatureDocument, FileMode.OpenOrCreate))
{
PdfStreamSigner signer = new PdfStreamSigner(outputStream);
signer.SignDocument(inputStream, signature1Field, pageIndex: 0, timeout: null);
}
}
// Create the second signature field.
SignatureField signature2Field = this.CreateSignatureField(
"SampleSignature2",
certificate,
new Point(50, 50),
20,
new Rect(500, 200, 100, 100)
);
string twoSignatureDocument = "twoSignatureDocument.pdf";
using (FileStream inputStream = File.OpenRead(oneSignatureDocument))
{
using (FileStream outputStream = new FileStream(twoSignatureDocument, FileMode.OpenOrCreate))
{
PdfStreamSigner signer = new PdfStreamSigner(outputStream);
signer.SignDocument(inputStream, signature2Field, pageIndex: 0, timeout: null);
}
}
}
private SignatureField CreateSignatureField(string signatureName, X509Certificate2 certificate, Point circleCenter, double circleRadius, Rect widgetRect)
{
// This is the Form XObject element that represents the contents of the signature field.
Form signatureForm = new Form();
signatureForm.FormSource = new FormSource();
signatureForm.FormSource.Size = new Size(120, 120);
// We will use the editor to fill the Form XObject.
FixedContentEditor formEditor = new FixedContentEditor(signatureForm.FormSource);
formEditor.DrawCircle(circleCenter, circleRadius);
formEditor.DrawText(signatureName);
// The Signature object is added to a signature field, so we can add a visualization to it.
SignatureField signatureField = new SignatureField(signatureName);
signatureField.Signature = new Telerik.Windows.Documents.Fixed.Model.DigitalSignatures.Signature(certificate);
// The widget contains the Form XObject and defines the appearance of the signature field.
SignatureWidget signatureWidget = signatureField.Widgets.AddWidget();
signatureWidget.Rect = widgetRect;
signatureWidget.Border = new AnnotationBorder(100, AnnotationBorderStyle.Solid, null);
signatureWidget.Content.NormalContentSource = signatureForm.FormSource;
return signatureField;
}
