Digital Signatures
Everything you need to know about Digital Signatures
What is Digital Signature?
Digital signing is a cryptographic process that ensures the authenticity and integrity of digital data. In simple terms, it is used for soft copies of documents (as opposed to hard copies) to verify their authors and signers while maintaining the privacy of the data they carry. This process is called digital signing.
What are main ways?
There are two primary methods to implement digital signing.
1. Symmetric Encryption
Symmetric encryption involves using the same key for both encryption and decryption.

2. Asymmetric Encryption
Asymmetric encryption, also known as public-key cryptography, uses a pair of keys
private key for signing.
public key for verification.

Coding…..
Add signatures
[HttpPost("stamp-signature-with-metadata-and-text-v2")]
public async Task<IActionResult> StampSignatureWithMetadataAndTextV2(IFormFile docFile, IFormFile signatureImage, [FromForm] string searchText, [FromForm] string signerUsername, [FromForm] string real_ref)
{
if (docFile == null || signatureImage == null || string.IsNullOrWhiteSpace(searchText) || string.IsNullOrWhiteSpace(signerUsername) || string.IsNullOrWhiteSpace(real_ref))
return BadRequest("Document, signature image, search text, reference number, and signer username are required.");
try
{
// Save the uploaded PDF to a temporary location
var tempPdfPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.pdf");
using (var docStream = new FileStream(tempPdfPath, FileMode.Create))
{
await docFile.CopyToAsync(docStream);
}
// Find text position and stamp signature with metadata
// [... truncated for brevity, see full implementation above ...]
// Return the signed PDF with metadata
var signedPdfBytes = System.IO.File.ReadAllBytes(tempSignedPdfPath);
return File(signedPdfBytes, "application/pdf", "SignedDocumentWithMetadata.pdf");
}
catch (Exception ex)
{
return StatusCode(500, $"Error during signing with metadata: {ex.Message}");
}
}
Read authors
[HttpPost("read-metadata-v2")]
public async Task<IActionResult> ReadMetadataV2(IFormFile docFile, [FromForm] string real_ref)
{
if (docFile == null || string.IsNullOrEmpty(real_ref))
return BadRequest("Document and ref are required.");
try
{
string DecryptSignerData(string encryptedSignerData, string realRef, string salt)
{
string combinedKey = realRef + salt;
// Ensure combined key is at least 16 characters long
if (combinedKey.Length < 16)
throw new ArgumentException("The combined key must be at least 16 characters.");
using (var aesAlg = Aes.Create())
{
aesAlg.Key = Encoding.UTF8.GetBytes(combinedKey.Substring(0, 16)); // AES requires 16-byte key
aesAlg.IV = Encoding.UTF8.GetBytes(combinedKey.Substring(0, 16)); // Use the same key for IV
using (var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV))
{
using (var msDecrypt = new MemoryStream(Convert.FromBase64String(encryptedSignerData)))
using (var cryptoStream = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (var reader = new StreamReader(cryptoStream))
{
return reader.ReadToEnd();
}
}
}
}
// Save the uploaded PDF to a temporary location
var tempPdfPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.pdf");
using (var docStream = new FileStream(tempPdfPath, FileMode.Create))
{
await docFile.CopyToAsync(docStream);
}
// Read metadata from the PDF
var metadata = new Dictionary<string, string>();
using (var pdfReader = new PdfReader(tempPdfPath))
{
metadata = pdfReader.Info ?? new Dictionary<string, string>();
if (metadata.ContainsKey("Signers"))
{
string encryptedSigners = metadata["Signers"];
if (!string.IsNullOrEmpty(encryptedSigners))
{
try
{
string decryptedSigners = DecryptSignerData(encryptedSigners, real_ref, "cnasCrypt");
metadata["DecryptedSigners"] = decryptedSigners; // Add decrypted data to the metadata dictionary
}
catch (Exception decryptEx)
{
return BadRequest($"Error decrypting signers data: {decryptEx.Message}");
}
}
}
}
// Clean up the temporary file
System.IO.File.Delete(tempPdfPath);
// Return metadata as JSON
return Ok(metadata);
}
catch (Exception ex)
{
return StatusCode(500, $"Error reading metadata: {ex.Message}");
}
}
The above code demonstrates how you can digitally sign documents using symmetric encryption. This approach is feasible due to the special criteria where the document contains a unique identifier. Otherwise, document signing typically relies on asymmetric encryption.