In addition to encrypting and digitally signing a PDF with an electronic certificate, storing the raw data of the signature, including point positions, velocity, and acceleration, can help strengthen the evidence. By generating and storing a hash of the raw signature data in the encrypted and digitally signed document and in a database, signed documents can be compared and validated.

Since version 32.0.2 of the Document Viewer, the SignatureData object contains the raw signature data. The SignaturePoint class stores the location of each captured signature point and a time stamp.

Learn More

During the e-signing process, the document is encrypted and digitally signed and is therefore tamper-proof. Additional features, such as storing the raw signature data, including point positions, velocity, and acceleration, can enhance the evidence.

E-Sign: Retrieving Timestamped Raw Signature Data

Signature Acquisition

This example shows how to extract the signature lines from the returned signature data and store a hash of it as an attachment to the created PDF document.

Signature Hash

The first step is to use the Document Viewer to capture a signature, which is then used to sign the document. To do this, click the Sign New Document button.

Signature Hash

Generating the Hash

The ProcessSignature method creates the hash from the signature data. This data is then stored in a local json database file.

[HttpPost]
public IActionResult ProcessSignature([FromBody] TXTextControl.Web.MVC.DocumentViewer.Models.SignatureData data)
{
if (data == null)
{
return BadRequest();
}
string signatureDataJson = JsonConvert.SerializeObject(data.SignatureLines);
string hash = CreateHash(signatureDataJson);
Envelope envelope = new Envelope
{
DocumentId = data.UniqueId,
SignatureHash = hash,
SignatureData = signatureDataJson
};
AddEnvelope(envelope);
if (SaveSignedPDF(data, envelope))
{
return Ok(true);
}
else
{
return StatusCode(500);
}
}
view raw test.cs hosted with ❤ by GitHub

The CreateHash method is the calculation of a SHA256 hash of the signature lines that have previously been serialized as JSON.

private string CreateHash(string json)
{
using (SHA256 sha256Hash = SHA256.Create())
{
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(json));
return BitConverter.ToString(bytes).Replace("-", "").ToLower();
}
}
view raw test.cs hosted with ❤ by GitHub

Embedding Attachment

The SaveSignedPDF method creates an EmbeddedFile TX Text Control .NET Server for ASP.NET
TXTextControl Namespace
EmbeddedFile Class
The EmbeddedFile class represents a file embedded in another document.
object that contains the hash of the signature lines along with the unique document ID and the actual signature data. The actual signature lines are not necessarily needed, but demonstrate the possibility in case the hash needs to be regenerated. Finally, a digital signature is applied and the embedded file is attached to the PDF document.

private bool SaveSignedPDF(TXTextControl.Web.MVC.DocumentViewer.Models.SignatureData data, Envelope envelope)
{
try
{
using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl())
{
tx.Create();
tx.Load(Convert.FromBase64String(data.SignedDocument.Document), TXTextControl.BinaryStreamType.InternalUnicodeFormat);
var embeddedFile = new EmbeddedFile($"tx-hash_{data.UniqueId}.txt", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(envelope)), null)
{
Relationship = "Data",
MIMEType = "application/json"
};
X509Certificate2 cert = new X509Certificate2("App_Data/textcontrolself.pfx", "123");
var saveSettings = new TXTextControl.SaveSettings
{
EmbeddedFiles = new EmbeddedFile[] { embeddedFile },
CreatorApplication = "TX Text Control Sample Application",
SignatureFields = new DigitalSignature[]
{
new TXTextControl.DigitalSignature(cert, null, "txsign")
}
};
var savePath = Path.Combine("App_Data/signed", $"{data.UniqueId}.pdf");
Directory.CreateDirectory(Path.GetDirectoryName(savePath));
tx.Save(savePath, TXTextControl.StreamType.AdobePDF, saveSettings);
}
return true;
}
catch (Exception)
{
return false;
}
}
view raw test.cs hosted with ❤ by GitHub

After the document is signed, it is listed in the summary table.

Signature Hash

Now click on the Download button to download the PDF document that was generated. You can see the attached text file in the Attachments tab when you open it in Acrobat Reader.

Signature Hash

If you open the attachment in a text editor, you will be able to see the json structure, including the hash value that was generated.

{
"DocumentId":"5df83af0-f456-4485-a29f-6290c523067b",
"SignatureHash":"7592d7e308a1aa3cf2c26f7226c572fc1c744a223a0c6eed0431312d807d23c0",
"SignatureData":"[[{\"X\":190.0,\"Y\":29.28125,\"CreationTimeStamp\":1698671635701},...]]"
}
view raw test.json hosted with ❤ by GitHub

Then click the Choose File button and select the file you downloaded. Confirm by clicking Validate Signature Hash. You should see the following page if the signature hash comparison was successful and the stored hashes match.

Signature Hash

Extracting the Hash

The Validate method extracts the hash information from the PDF and compares the stored hash values from the document and the local database file.

public IActionResult Validate([FromForm] IFormFile file)
{
if (file == null)
{
return NotFound();
}
byte[] bPDF = GetBytesFromFormFile(file);
var uploadedEnvelope = ExtractEnvelopeFromPDF(bPDF);
if (uploadedEnvelope == null)
{
return NotFound();
}
var envelopes = LoadEnvelopesFromJson();
var envelope = envelopes.FirstOrDefault(e => e.DocumentId == uploadedEnvelope.DocumentId);
if (envelope != null && envelope.SignatureHash == uploadedEnvelope.SignatureHash)
{
return View(true);
}
return View(false);
}
view raw test.cs hosted with ❤ by GitHub

The ExtractEnvelopeFromPDF method uses the ServerTextControl TX Text Control .NET Server for ASP.NET
TXTextControl Namespace
ServerTextControl Class
The ServerTextControl class implements a component that provide high-level text processing features for server-based applications.
class to load the PDF document and extract the attachment from the EmbeddedFiles TX Text Control .NET Server for ASP.NET
TXTextControl Namespace
LoadSaveSettingsBase Class
EmbeddedFiles Property
Specifies an array of EmbeddedFile objects which will be embedded in the saved document.
property.

private Envelope ExtractEnvelopeFromPDF(byte[] document)
{
using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl())
{
tx.Create();
var loadSettings = new TXTextControl.LoadSettings
{
EmbeddedFiles = new EmbeddedFile[] { },
};
tx.Load(document, TXTextControl.BinaryStreamType.AdobePDF, loadSettings);
var embeddedFile = loadSettings.EmbeddedFiles
.FirstOrDefault(ef => ef.FileName.StartsWith("tx-hash_"));
if (embeddedFile != null)
{
return JsonConvert.DeserializeObject<Envelope>(Encoding.UTF8.GetString((byte[])embeddedFile.Data));
}
}
return null;
}
view raw test.cs hosted with ❤ by GitHub

Conclusion

The storage and comparison of signature raw data hash values is a powerful feature that can add an extra layer of security and trust to e-signature workflows.

You will be able to test the sample by downloading it from our GitHub repository.