The document signing process is an important process in many business use cases that guarantees the creation of binding obligations between two or more parties.

Typically, digital signature online services such as DocuSign or Adobe Sign are used as trusted third-parties to prove the authenticity. Therefore, all documents are stored on their third-party servers to be validated.

The PDF specification includes security features including password protection, digital signatures and encryption. These digital signatures are added to the PDF to verify who created and encrypted the document. PDF documents created with TX Text Control can be easily digitally signed which is explained in this article:

Digitally Sign Adobe PDF Documents Using Simple Digital IDs

But depending on the algorithm that is used, it is not challenging to sabotage the protection.

Using Blockchain to Validate Documents

The blockchain technology can be used to store any data in a block. Basically, a blockchain is a data structure that invalidates previous entries automatically and the integrity can be easily proofed.

In this sample project, we implemented a very basic blockchain to store a checksum of a PDF that has been created using TX Text Control. The implemented blockchain contains a challenge, but is not distributed. Even without a distributed ledger, this technology can be used to validate documents. The Blockchain class consists of a list of Block objects. The Block object itself stores our data (an MD5 checksum and additional data), a time stamp, the previous hash and the current hash. Based on this linked list, every block can be validated by comparing the hash of the previous block with the current hash.

Blockchain implementation

The hash itself is mined and is calculated based on the time stamp, the previous block hash, the data itself and a value called nonce. A nonce ("number only used once") is a number added to the block hash that, when rehashed, meets the difficulty level restrictions.

// generates a new hash for the block including the time stamp,
// the previous block has, the data and the nonce.
internal string GenerateBlockHash()
{
SHA256 sha256 = SHA256.Create();
byte[] bInput =
Encoding.ASCII.GetBytes($"{TimeStamp}-{PreviousBlockHash ?? ""}-{Data}-{Nonce}");
byte[] bOutput = sha256.ComputeHash(bInput);
return Convert.ToBase64String(bOutput);
}
// this method is generating hashes until a new hash with a specific
// number of leading zeros is created
public void Mine(int difficulty)
{
string sLeadingZeros = new string('0', difficulty);
while (this.BlockHash == null
|| this.BlockHash.Substring(0, difficulty) != sLeadingZeros)
{
this.Nonce++;
this.BlockHash = this.GenerateBlockHash();
}
}
view raw data.cs hosted with ❤ by GitHub

When starting the sample project, you have two options: Sign Document and Validate Document.

Blockchain sample

In a first step, a random document needs to be signed using the TX Text Control DocumentViewer for ASP.NET MVC. The signature is created:

Blockchain sample

And the document is signed:

Blockchain sample

After all signatures are done, the document needs to be submitted:

Blockchain sample

When the document has been successfully submitted, it is getting stored on the blockchain using an HTTP endpoint. The document gets loaded into a temporary ServerTextControl and exported as PDF. If a blockchain exists for this document, it is opened and a new block is added with the MD5 checksum. The document and the unique document ID is returned to the client:

// this method stores the document hash in the blockchain
[System.Web.Http.HttpPost]
public ActionResult StoreDocument(
[FromBody] string Document,
[FromBody] string UniqueId,
[FromBody] string SignerName)
{
byte[] bPDF;
// create temporary ServerTextControl
using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl())
{
tx.Create();
// load the document
tx.Load(Convert.FromBase64String(Document),
TXTextControl.BinaryStreamType.InternalUnicodeFormat);
TXTextControl.SaveSettings saveSettings = new TXTextControl.SaveSettings()
{
CreatorApplication = "TX Text Control Sample Application",
};
// save the document as PDF
tx.Save(out bPDF, TXTextControl.BinaryStreamType.AdobePDF, saveSettings);
}
// calculate the MD5 checksum of the binary data
// and store in SignedDocument object
SignedDocument document = new SignedDocument()
{
Checksum = Checksum.CalculateMD5(bPDF)
};
// define a Blockchain object
Blockchain bcDocument;
// if the blockchain exists, load it
if (System.IO.File.Exists(
Server.MapPath("~/App_Data/Blockchains/" + UniqueId + ".bc")))
{
string bc = System.IO.File.ReadAllText(
Server.MapPath("~/App_Data/Blockchains/" + UniqueId + ".bc"));
bcDocument = JsonConvert.DeserializeObject<Blockchain>(bc);
}
else
bcDocument = new Blockchain(true); // otherwise create a new blockchain
// add a new block to the blockchain and store the SignedDocument object
bcDocument.AddBlock(new Block(DateTime.Now, null, JsonConvert.SerializeObject(document)));
// store the blockchain as a file
System.IO.File.WriteAllText(
Server.MapPath("~/App_Data/Blockchains/" + UniqueId + ".bc"),
JsonConvert.SerializeObject(bcDocument));
// create and return a view model with the PDF and the unique document ID
StoredDocument storedDocument = new StoredDocument()
{
PDF = Convert.ToBase64String(bPDF),
DocumentId = UniqueId
};
return new JsonResult() { Data = storedDocument,
JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
view raw data.cs hosted with ❤ by GitHub

The returned document can be downloaded by the user and the validation view is opened automatically. The Unique Document ID is pre-filled into the text box. After clicking Choose File, choose the previously downloaded PDF document (the name of the file is the unique document id) and click Validate Document.

Blockchain sample

The HTTP endpoint ValidateDocument accepts a PDF document and the unique document ID to validate the document based on the last block in the blockchain. It creates an MD5 checksum of the uploaded PDF document and compares it with the stored checksum in the blockchain. If the values are equal, the uploaded document has not been manipulated and is therefore considered to be valid.

You can try this last validation step by uploading a different or manipulated PDF document. You will see that the document won't be validated:

Blockchain sample

// this method validates a document with the last block on the blockchain
[System.Web.Http.HttpPost]
public bool ValidateDocument([FromBody] string Document, [FromBody] string UniqueId)
{
if (Document == null || UniqueId == null)
return false;
// calculate the MD5 of the uploaded document
string sChecksum = Checksum.CalculateMD5(Convert.FromBase64String(Document));
Blockchain newDocument;
// load the associated blockchain
if (System.IO.File.Exists(
Server.MapPath("~/App_Data/Blockchains/" + UniqueId + ".bc")))
{
string bc = System.IO.File.ReadAllText(
Server.MapPath("~/App_Data/Blockchains/" + UniqueId + ".bc"));
newDocument = JsonConvert.DeserializeObject<Blockchain>(bc);
// get the SignedDocument object from the block
SignedDocument signedDocument =
JsonConvert.DeserializeObject<SignedDocument>(newDocument.GetCurrentBlock().Data);
// compare the checksum in the stored block
// with the checksum of the uploaded document
if (signedDocument.Checksum == sChecksum)
return true; // document valid
else
return false; // not valid
}
else
return false; // blockchain doesn't exist
}
view raw data.cs hosted with ❤ by GitHub

The whole process is visualized in the following diagram:

Blockchain diagram

Conclusion

A blockchain can be used to store document checksums to validate a document. The blockchain always contains information about the most current version of an uploaded or signed document. The game changing advantage is that documents must not be stored on third-party servers to be validated.

You can download this sample application from our GitHub repository.