ASP.NET Core : Create and Verify Digital Signatures on Documents

What is a Digital Signature?

A digital signature is a cryptographic technique used to ensure the authenticity, integrity, and non-repudiation of digital documents or messages. It involves generating a unique digital fingerprint of the document using a private key and verifying it using a corresponding public key.

Why Digital Signatures?

Digital signatures provide a secure method for ensuring the origin and integrity of electronic documents. They are widely used in electronic transactions, legal contracts, and secure communication protocols to prevent tampering and unauthorized access.

When to Use Digital Signatures?

Digital signatures are particularly useful when dealing with sensitive or legally binding documents, such as contracts, financial transactions, and official records. They provide a way to securely validate the authenticity and integrity of electronic data.

How to Create and Verify Digital Signatures in ASP.NET Core

To create and verify digital signatures on documents in ASP.NET Core, you can use cryptographic libraries like BouncyCastle or .NET's built-in System.Security.Cryptography namespace. Below, I'll outline the steps to create and verify digital signatures using .NET's built-in RSACryptoServiceProvider class.

Create Digital Signature

using System;
using System.Security.Cryptography;
using System.Text;

public class DigitalSignatureService
{
    public byte[] CreateDigitalSignature(string document, RSAParameters privateKey)
    {
        using (var rsa = new RSACryptoServiceProvider())
        {
            rsa.ImportParameters(privateKey);

            byte[] data = Encoding.UTF8.GetBytes(document);
            byte[] signature = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            
            return signature;
        }
    }
}

Verify Digital Signature

public class DigitalSignatureService
{
    public bool VerifyDigitalSignature(string document, byte[] signature, RSAParameters publicKey)
    {
        using (var rsa = new RSACryptoServiceProvider())
        {
            rsa.ImportParameters(publicKey);

            byte[] data = Encoding.UTF8.GetBytes(document);
            bool isVerified = rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            
            return isVerified;
        }
    }
}

Usage

public class SignatureController : Controller
{
    private readonly DigitalSignatureService _signatureService;

    public SignatureController(DigitalSignatureService signatureService)
    {
        _signatureService = signatureService;
    }

    public IActionResult SignDocument(string document)
    {
        RSAParameters privateKey; // Load private key from secure storage
        byte[] signature = _signatureService.CreateDigitalSignature(document, privateKey);
        
        // Save or send the signature along with the document
        return Ok(Convert.ToBase64String(signature));
    }

    public IActionResult VerifySignature(string document, string signatureString)
    {
        byte[] signature = Convert.FromBase64String(signatureString);
        RSAParameters publicKey; // Load public key from sender or trusted source
        bool isVerified = _signatureService.VerifyDigitalSignature(document, signature, publicKey);
        
        if (isVerified)
            return Ok("Signature is valid.");
        else
            return BadRequest("Signature verification failed.");
    }
}

Note

  • Ensure that you securely store the private key and distribute the public key to verify the signature.
  • This is a simplified example; in production, consider additional security measures such as key management, input validation, and secure communication channels.

Implementation in ASP.NET Core

In an ASP.NET Core application, you can encapsulate the digital signature functionality in a service class. This service class can be injected into controllers or other components where digital signatures are needed.

using System;
using System.Security.Cryptography;
using System.Text;

namespace DigitalSignatureDemo.Services
{
    public class DigitalSignatureService : IDigitalSignatureService
    {
        private const string KeyContainerName = "MyKeyContainer";

        public string CreateDigitalSignature(string data)
        {
            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.PersistKeyInCsp = false;
                rsa.FromXmlString(GetOrCreateKey());
                var dataBytes = Encoding.UTF8.GetBytes(data);
                var signatureBytes = rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
                return Convert.ToBase64String(signatureBytes);
            }
        }

        public bool VerifyDigitalSignature(string data, string signature)
        {
            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.PersistKeyInCsp = false;
                rsa.FromXmlString(GetOrCreateKey());
                var dataBytes = Encoding.UTF8.GetBytes(data);
                var signatureBytes = Convert.FromBase64String(signature);
                return rsa.VerifyData(dataBytes, signatureBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            }
        }

        private string GetOrCreateKey()
        {
            var cspParams = new CspParameters
            {
                KeyContainerName = KeyContainerName,
                Flags = CspProviderFlags.UseMachineKeyStore | CspProviderFlags.UseExistingKey
            };

            using (var rsa = new RSACryptoServiceProvider(2048, cspParams))
            {
                return rsa.ToXmlString(true);
            }
        }
    }
}

This code defines a service class, DigitalSignatureService, that provides methods for creating and verifying digital signatures using the RSA algorithm. The CreateDigitalSignature method takes a string input data and returns a base64-encoded string representing the digital signature. The VerifyDigitalSignature method takes the input data and signature and verifies whether the signature is valid for the given data.

The GetOrCreateKey method is used to retrieve an existing RSA key pair from the key container named "MyKeyContainer" or create a new key pair if it doesn't exist.

You can inject this service into your ASP.NET Core controllers or services to incorporate digital signature functionality into your application.

Conclusion

Digital signatures play a crucial role in ensuring the authenticity and integrity of electronic documents in ASP.NET Core applications. By following the steps outlined above, developers can implement robust digital signature functionality to secure their applications and data.