Security ASP.net Core MVC (C#) Encryption and Decryption

Overview

In the realm of ASP.NET Core MVC, harnessing the power of C# to fortify our data security through encryption and decryption is a versatile and essential capability. This security enhancement is made possible through the utilization of a range of encryption algorithms, including but not limited to AES (Advanced Encryption Standard), RSA (Rivest-Shamir-Adleman), DES (Data Encryption Standard), and many more. These cryptographic techniques empower developers to safeguard sensitive information, ensuring it remains confidential and tamper-resistant.

Let's delve into a practical illustration of how the AES algorithm, known for its robust encryption capabilities, can be seamlessly integrated into our ASP.NET Core MVC application to both encrypt and decrypt data. This example serves as a foundational understanding of encryption processes within the ASP.NET Core MVC framework, providing a starting point for developers to explore and implement advanced security measures in their web applications.

By the end of this demonstration, we'll have a clearer grasp of how to employ the AES algorithm within our ASP.NET Core MVC projects, bolstering our ability to secure and protect critical data assets. This knowledge empowers us to make informed decisions about which encryption techniques best suit our application's unique security requirements, ensuring the utmost protection for our users' sensitive information.

Step 1. Implement an Encryption and Decryption Helper Class

Generally, it is recommended to create a dedicated helper class to carry out encryption and decryption operations within our application. Below is a well-structured example of such a class that can be used to enhance the security of our application.

using System.Security.Cryptography;

namespace ZR.CodeExample.SecureMVC.Helpers
{
    public static class EncryptionHelper
    {
        private static readonly string EncryptionKey = GenerateRandomKey(256);
        
        public static string Encrypt(string plainText)
        {
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Convert.FromBase64String(EncryptionKey);
                aesAlg.IV = GenerateRandomIV(); // Generate a random IV for each encryption

                aesAlg.Padding = PaddingMode.PKCS7; // Set the padding mode to PKCS7

                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(plainText);
                        }
                    }
                    return Convert.ToBase64String(aesAlg.IV.Concat(msEncrypt.ToArray()).ToArray());
                }
            }
        }

        public static string Decrypt(string cipherText)
        {
            byte[] cipherBytes = Convert.FromBase64String(cipherText);

            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Convert.FromBase64String(EncryptionKey);
                aesAlg.IV = cipherBytes.Take(16).ToArray();

                aesAlg.Padding = PaddingMode.PKCS7; // Set the padding mode to PKCS7

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream msDecrypt = new MemoryStream(cipherBytes, 16, cipherBytes.Length - 16))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            return srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
        }

        private static byte[] GenerateRandomIV()
        {
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.GenerateIV();
                return aesAlg.IV;
            }
        }

        private static string GenerateRandomKey(int keySizeInBits)
        {
            // Convert the key size to bytes
            int keySizeInBytes = keySizeInBits / 8;

            // Create a byte array to hold the random key
            byte[] keyBytes = new byte[keySizeInBytes];

            // Use a cryptographic random number generator to fill the byte array
            using (var rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(keyBytes);
            }

            // Convert the byte array to a base64-encoded string for storage
            return Convert.ToBase64String(keyBytes);
        }

    }
}

As the name implies, this helper class encapsulates the encryption and decryption logic, making it easier to secure sensitive data in our ASP.NET Core MVC application. We generate the encryption key dynamically as part of best practice. GenerateRandomKey(256)

By encapsulating the encryption and decryption logic in a dedicated helper class, we ensure the security of our application is enhanced. This approach allows us to easily handle sensitive data within our ASP.NET Core MVC application, providing an extra layer of protection.

Step 2. Utilise Encryption and Decryption in Our Controller or Service

We will be required to call the Encrypt and Decrypt methods within our controller or service class in order to take advantage of the encryption and decryption capabilities we've integrated. Here's an example of how to do this in detail.

using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using ZR.CodeExample.SecureMVC.Helpers;
using ZR.CodeExample.SecureMVC.Models;

namespace ZR.CodeExample.SecureMVC.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {
            // Define the data you want to secure
            string plainText = "I am Ziggy Rafiq from United Kingdom";

            // Encrypt the data using the EncryptionHelper
            string cipherText = EncryptionHelper.Encrypt(plainText);

            // Decrypt the data to retrieve the original content
            string decryptedText = EncryptionHelper.Decrypt(cipherText);

            // Store the encrypted and decrypted data in ViewData for use in your view
            ViewData["CipherText"] = cipherText;
            ViewData["DecryptedText"] = decryptedText;

            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

During the development of this example, we've assumed that we have created a separate namespace that contains the EncryptionHelper class, which we should replace with a namespace that contains our actual code.

To ensure the utmost security, it is crucial to never hardcode our encryption key directly into our code, as shown in the EncryptionHelper class. Instead, we should consider more secure methods like storing it in an environment variable or a protected configuration file. By adopting this practice, we effectively keep sensitive information out of our source code, minimizing the risk of unauthorized access.

Implementing encryption and decryption in our controller or service class allows us to fully leverage the encryption capabilities we've integrated into our ASP.NET Core MVC application. This enables us to secure and protect critical data assets, ensuring the confidentiality and integrity of our users' sensitive information.

Remember, choosing the right encryption techniques that align with our application's unique security requirements is essential. By making informed decisions, we can safeguard our users' data effectively and maintain a high level of security in our web applications.

Step 3. Display Encrypted and Decrypted Data in the View

One of the powerful features of Razor views is their ability to display both encrypted and decrypted data that is stored in the ViewData dictionary of our controller. By leveraging this capability, we can effectively present sensitive information to our users in a secure manner. Let's take a look at an example of how we can accomplish this within a Razor view.

@{
    ViewData["Title"] = "Security ASP.net Core MVC (C#) Encryption and Decryption";
}

<div class="text-center">
    <h1 class="display-4">@ViewData["Title"]</h1>
    <p>By Ziggy Rafiq, delve into the intricacies of security in ASP.NET Core MVC (C#) through our comprehensive article, focusing on the vital aspects of encryption and decryption techniques. Learn how to safeguard your web applications effectively.</p>
</div>
<div>
    <h2>Encrypted Text:</h2>
    <p>@ViewData["CipherText"]</p>
</div>

<div>
    <h2>Decrypted Text:</h2>
    <p>@ViewData["DecryptedText"]</p>
</div>
<div>
    <h3>Who is Ziggy Rafiq?</h3>
    <p>I am Ziggy Rafiq, a seasoned Technical Lead Developer, recognized as a C# Corner MVP and VIP. With over 19 years of extensive experience, I am passionate about sharing my knowledge as a speaker, mentor, and trainer. Currently, I am proud to be a part of the Capgemini team, contributing my expertise to drive innovation and excellence in the field of software development.</p>
</div>

In this code snippet, we assume that our controller action is associated with a view, such as Index.cshtml. By utilizing this Razor view, we can showcase the encrypted and decrypted text on the web page. Additionally, we have the flexibility to customize the HTML structure and styling to align with the design and requirements of our application.

Summary

In the dynamic and ever-changing landscape of ASP.NET Core MVC, prioritizing data security is of utmost importance. As developers, we must equip ourselves with the necessary skills to effectively encrypt and decrypt data. Throughout this journey into the world of ASP.NET Core MVC, powered by the versatile C# language, we have explored various methods to strengthen the security of our data.

Encryption serves as a robust shield against unauthorized access and tampering. By leveraging encryption algorithms such as AES, RSA, and DES, developers are empowered to protect sensitive information with confidentiality and integrity. Through our practical exploration, we focused on the formidable AES algorithm, renowned for its encryption capabilities. We seamlessly integrated this algorithm into the ASP.NET Core MVC framework, showcasing how to encrypt and decrypt data effectively. This exercise provided us with a foundational understanding of encryption processes within the framework, enabling us to implement advanced security measures in our web applications.

As we conclude this demonstration, we can confidently apply the AES algorithm in our ASP.NET Core MVC projects to enhance data security. Armed with this newfound knowledge, we are equipped to make informed decisions regarding encryption techniques that align with the unique security requirements of our applications. By doing so, we can ensure the utmost protection for our users' sensitive information.

In wrapping up our journey, we not only fortified the security of our data but also gained valuable insights into the ever-evolving landscape of web application security. As developers, we are continually evolving, and these insights will serve as a steadfast guide in our quest to safeguard critical data assets.

The Code Examples are available on my GitHub Repository:  https://github.com/ziggyrafiq/SecureMVC

Please do not forget to follow me on LinkedIn https://www.linkedin.com/in/ziggyrafiq/ and click the like button if you have found this article useful/helpful.