How to sign and verify updates to a PDF document
How to sign and verify updates to a PDF document
This code sample shows how you can sign PDF documents and how to handle updates to form data.
using (FileStream sourceFile = new FileStream(@"..\..\form.pdf", FileMode.Open, FileAccess.Read))
{
// open the form
Document document = new Document(sourceFile);
// file out the data fields
TextField projectNr = document.Fields["projectNumber"] as TextField;
projectNr.Value = "FF-235";
TextField sName = document.Fields["studentName"] as TextField;
sName.Value = "Bob Stapleton";
TextField sDate = document.Fields["studentDate"] as TextField;
sDate.Value = "April 18, 2007";
// retrieve the signature field
SignatureField sigField = document.Fields["studentSignature"] as SignatureField;
// open certicate store.
Pkcs12Store store = null;
using (FileStream storeFile = new FileStream(@"..\..\BobStapleton.pfx", FileMode.Open, FileAccess.Read))
{
store = new Pkcs12Store(storeFile, "studentpassword");
}
// let the factory decide which type should be used.
SignatureHandler handler = StandardSignatureHandler.Create(store);
// associate the handler with the signature field
sigField.SignatureHandler = handler;
// set optional info.
sigField.ContactInfo = "+31 (0)77 4748677";
sigField.Location = "The Netherlands";
sigField.Reason = "I hereby declare!";
// save the signed document - while saving, the handler
// will be called to sign the saved content
using (FileStream outFile = new FileStream(@"..\..\signedByStudent.pdf", FileMode.Create, FileAccess.ReadWrite))
{
document.Write(outFile);
}
}
// -----------------------------------------------------
// TEACHER FILLS OUT FINAL FIELDS AND SIGNS THE DOCUMENT
// -----------------------------------------------------
using (FileStream sourceFile = new FileStream(@"..\..\signedByStudent.pdf", FileMode.Open, FileAccess.Read))
{
// open the form
Document document = new Document(sourceFile);
// file out the data fields
TextField tName = document.Fields["teacherName"] as TextField;
tName.Value = "Max Boulton";
TextField tDate = document.Fields["teacherDate"] as TextField;
tDate.Value = "April 18, 2007";
// retrieve the signature field
SignatureField sigField = document.Fields["teacherSignature"] as SignatureField;
// open certicate store.
Pkcs12Store store = null;
using (FileStream storeFile = new FileStream(@"..\..\MaxBoulton.pfx", FileMode.Open, FileAccess.Read))
{
store = new Pkcs12Store(storeFile, "teacherpassword");
}
// let the factory decide which type should be used.
SignatureHandler handler = StandardSignatureHandler.Create(store);
// associate the handler with the signature field
sigField.SignatureHandler = handler;
// set optional info.
sigField.ContactInfo = "+31 (0)77 4748677";
sigField.Location = "The Netherlands";
sigField.Reason = "I hereby declare!";
// save the signed document - while saving, the handler
// will be called to sign the saved content
using (FileStream outFile = new FileStream(@"..\..\signedByTeacher.pdf", FileMode.Create, FileAccess.ReadWrite))
{
document.Write(outFile, DocumentWriteMode.AppendUpdate);
}
}
// ----------------------------------------------------
// ENUMERATE UPDATES IN DOCUMENT THAS BEEN SIGNED TWICE
// ----------------------------------------------------
using (FileStream sourceFile = new FileStream(@"..\..\signedByTeacher.pdf", FileMode.Open, FileAccess.Read))
{
// open the form
Document document = new Document(sourceFile);
// count the number of updates
//Console.WriteLine( "This document has {0} updates.", document.Updates.Count );
// save each update as a new PDF document
foreach (Update update in document.Updates)
{
string name = string.Format( @"..\..\signedByTeacher_{0}.pdf", update.Index );
using (FileStream updateFile = new FileStream(name, FileMode.Create, FileAccess.Write))
{
update.Write(updateFile);
}
}
}
// -----------------------------------------------------------
// ENUMERATE SIGNATURE FIELDS AND SAVE SIGNED UPDATE PER FIELD
// -----------------------------------------------------------
using (FileStream sourceFile = new FileStream(@"..\..\signedByTeacher.pdf", FileMode.Open, FileAccess.Read))
{
// open the form
Document document = new Document(sourceFile);
foreach (Field field in document.Fields)
{
// is this a signature field?
SignatureField sigField = field as SignatureField;
if (null != sigField)
{
// has it been signed?
if (sigField.IsSigned)
{
// save the update and name it after the field
string name = string.Format(@"..\..\{0}.pdf", sigField.FullName);
using (FileStream updateFile = new FileStream(name, FileMode.Create, FileAccess.Write))
{
sigField.SignedUpdate.Write(updateFile);
}
}
}
}
}
// ----------------------------------
// DUMP STATE OF EACH SIGNATURE FIELD
// ----------------------------------
using (FileStream inFile = new FileStream(@"..\..\signedByTeacher.pdf", FileMode.Open, FileAccess.Read))
{
// open form
Document document = new Document(inFile);
foreach (Field field in document.Fields)
{
// is this a signature field?
SignatureField sigField = field as SignatureField;
if (null != sigField)
{
Console.WriteLine("Field '{0}'", sigField.FullName);
// has it been signed?
if (sigField.IsSigned)
{
// verify, based on the default handlers.
bool verified = sigField.Verify();
Console.WriteLine(" -- {0}", verified ? "Verified" : "Not verified");
if (verified)
{
// has the document been modified after signing?
bool modified = sigField.DocumentModifiedAfterSigning;
Console.WriteLine(" -- {0}", modified ? "Modified after signing" : "Not modified after signing");
}
}
else
{
Console.WriteLine(" -- Not signed", sigField.FullName);
}
}
}
}
' -------------------------------------------
' STUDENT FILLS OUT FIELDS AND SIGNS DOCUMENT
' -------------------------------------------
Using sourceFile As New FileStream("..\..\form.pdf", FileMode.Open, FileAccess.Read)
' open the form
Dim document As New Document(sourceFile)
' file out the data fields
Dim projectNr As TextField = TryCast(document.Fields("projectNumber"), TextField)
projectNr.Value = "FF-235"
Dim sName As TextField = TryCast(document.Fields("studentName"), TextField)
sName.Value = "Bob Stapleton"
Dim sDate As TextField = TryCast(document.Fields("studentDate"), TextField)
sDate.Value = "April 18, 2007"
' retrieve the signature field
Dim sigField As SignatureField = TryCast(document.Fields("studentSignature"), SignatureField)
' open certicate store.
Dim store As Pkcs12Store = Nothing
Using storeFile As New FileStream("..\..\BobStapleton.pfx", FileMode.Open, FileAccess.Read)
store = New Pkcs12Store(storeFile, "studentpassword")
End Using
' let the factory decide which type should be used.
Dim handler As SignatureHandler = StandardSignatureHandler.Create(store)
' associate the handler with the signature field
sigField.SignatureHandler = handler
' set optional info.
sigField.ContactInfo = "+31 (0)77 4748677"
sigField.Location = "The Netherlands"
sigField.Reason = "I hereby declare!"
' save the signed document - while saving, the handler
' will be called to sign the saved content
Using outFile As New FileStream("..\..\signedByStudent.pdf", FileMode.Create, FileAccess.ReadWrite)
document.Write(outFile)
End Using
End Using
' -----------------------------------------------------
' TEACHER FILLS OUT FINAL FIELDS AND SIGNS THE DOCUMENT
' -----------------------------------------------------
Using sourceFile As New FileStream("..\..\signedByStudent.pdf", FileMode.Open, FileAccess.Read)
' open the form
Dim document As New Document(sourceFile)
' file out the data fields
Dim tName As TextField = TryCast(document.Fields("teacherName"), TextField)
tName.Value = "Max Boulton"
Dim tDate As TextField = TryCast(document.Fields("teacherDate"), TextField)
tDate.Value = "April 18, 2007"
' retrieve the signature field
Dim sigField As SignatureField = TryCast(document.Fields("teacherSignature"), SignatureField)
' open certicate store.
Dim store As Pkcs12Store = Nothing
Using storeFile As New FileStream("..\..\MaxBoulton.pfx", FileMode.Open, FileAccess.Read)
store = New Pkcs12Store(storeFile, "teacherpassword")
End Using
' let the factory decide which type should be used.
Dim handler As SignatureHandler = StandardSignatureHandler.Create(store)
' associate the handler with the signature field
sigField.SignatureHandler = handler
' set optional info.
sigField.ContactInfo = "+31 (0)77 4748677"
sigField.Location = "The Netherlands"
sigField.Reason = "I hereby declare!"
' save the signed document - while saving, the handler
' will be called to sign the saved content
Using outFile As New FileStream("..\..\signedByTeacher.pdf", FileMode.Create, FileAccess.ReadWrite)
document.Write(outFile, DocumentWriteMode.AppendUpdate)
End Using
End Using
' ----------------------------------------------------
' ENUMERATE UPDATES IN DOCUMENT THAS BEEN SIGNED TWICE
' ----------------------------------------------------
Using sourceFile As New FileStream("..\..\signedByTeacher.pdf", FileMode.Open, FileAccess.Read)
' open the form
Dim document As New Document(sourceFile)
' count the number of updates
'Console.WriteLine( "This document has {0} updates.", document.Updates.Count );
' save each update as a new PDF document
For Each update As Update In document.Updates
Dim name As String = String.Format("..\..\signedByTeacher_{0}.pdf", update.Index)
Using updateFile As New FileStream(name, FileMode.Create, FileAccess.Write)
update.Write(updateFile)
End Using
Next
End Using
' -----------------------------------------------------------
' ENUMERATE SIGNATURE FIELDS AND SAVE SIGNED UPDATE PER FIELD
' -----------------------------------------------------------
Using sourceFile As New FileStream("..\..\signedByTeacher.pdf", FileMode.Open, FileAccess.Read)
' open the form
Dim document As New Document(sourceFile)
For Each field As Field In document.Fields
' is this a signature field?
Dim sigField As SignatureField = TryCast(field, SignatureField)
If sigField IsNot Nothing Then
' has it been signed?
If sigField.IsSigned Then
' save the update and name it after the field
Dim name As String = String.Format("..\..\{0}.pdf", sigField.FullName)
Using updateFile As New FileStream(name, FileMode.Create, FileAccess.Write)
sigField.SignedUpdate.Write(updateFile)
End Using
End If
End If
Next
End Using
' ----------------------------------
' DUMP STATE OF EACH SIGNATURE FIELD
' ----------------------------------
Using inFile As New FileStream("..\..\signedByTeacher.pdf", FileMode.Open, FileAccess.Read)
' open form
Dim document As New Document(inFile)
For Each field As Field In document.Fields
' is this a signature field?
Dim sigField As SignatureField = TryCast(field, SignatureField)
If sigField IsNot Nothing Then
Console.WriteLine("Field '{0}'", sigField.FullName)
' has it been signed?
If sigField.IsSigned Then
' verify, based on the default handlers.
Dim verified As Boolean = sigField.Verify()
Console.WriteLine(" -- {0}", IIf(verified, "Verified", "Not verified"))
If verified Then
' has the document been modified after signing?
Dim modified As Boolean = sigField.DocumentModifiedAfterSigning
Console.WriteLine(" -- {0}", IIf(modified, "Modified after signing", "Not modified after signing"))
End If
Else
Console.WriteLine(" -- Not signed", sigField.FullName)
End If
End If
Next
End Using