Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
150 views

Part - 3 Encryption and Decryption in ASP - NET Core Web API

Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
150 views

Part - 3 Encryption and Decryption in ASP - NET Core Web API

Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 13

Encryption and Decryption in ASP.

NET Core Web API

What is Encryption?
Encryption is the process of converting plain text or other forms of readable data into an unreadable
format called ciphertext. This prevents unauthorized access, ensuring that only those with the correct
decryption key can access the original data. In ASP.NET Core Web API, we encrypt the sensitive data
before sending it over the network to the clients.

What is Decryption?
Decryption is the process of converting encrypted data back into its original form (plaintext). This is
typically done using a key that was used during the encryption process. In ASP.NET Core Web API,
decryption is used when data is received in an encrypted form and needs to be processed or
displayed.

Techniques for Encryption and Decryption:


 Symmetric Encryption: In the case of Symmetric Encryption, it uses the same key for both
encryption and decryption. For examples, AES (Advanced Encryption Standard,
Recommended Approach) and DES (Data Encryption Standard, not Recommended).
 Asymmetric Encryption: Uses a pair of keys (public and private). The public key encrypts
data, and the private key decrypts it. For example, RSA.

What is Advanced Encryption Standard (AES) Algorithm?


The Advanced Encryption Standard (AES) is a symmetric key encryption algorithm used widely
across the world to secure data. It was established as an encryption standard by the U.S. National
Institute of Standards and Technology (NIST) in 2001. AES is used to protect sensitive information in
both government and commercial sectors.

AES Algorithm Working Flow:


AES uses the same key for both encrypting and decrypting data, which means both the sender and
the receiver must have access to the same secret key. To understand the AES Algorithm Working
Flow, please have a look at the following diagram.

Let us understand each term and working flow of AES Algorithm:


 Sender: The sender is the entity (can be a person, system, or device) that initiates the
encryption process. The sender has plaintext that they wish to securely transmit to a receiver.
 Plaintext: Plaintext refers to the original readable data or message that needs to be
encrypted. Here, plaintext could be any sensitive data that needs to be encrypted before
being sent over the internet, such as passwords or personal information. In the context of
AES, the plaintext is processed in fixed-size blocks (typically 128 bits) during the encryption
process.
 Secret Key: The secret key is a parameter used in the AES algorithm to encrypt and decrypt
messages. It must be known only to the sender and the receiver to maintain security. The
secret key should be securely stored and managed to maintain the confidentiality of the key.
In AES, the key can be 128, 192, or 256 bits long, depending on the level of security required.
 Encryption Server: An encryption server is a dedicated server or service that performs the
encryption process. In a typical setup, it receives plaintext and a secret key from the sender,
encrypts the data using AES, and then sends the ciphertext to the intended receiver or makes
it available for secure transmission.
 Secure Channel: A secure channel is a method of communication that ensures the
confidentiality and integrity of the data transmitted between sender and receiver. It is secured
typically through the use of cryptographic techniques and protocols to prevent unauthorized
access and tampering during transmission.
 Ciphertext: Ciphertext is the encrypted version of the plaintext produced by the AES
algorithm that is unreadable without the appropriate decryption key. The ciphertext is what is
transmitted over the secure channel from the sender to the receiver ensure that sensitive data
cannot be read if intercepted.
 Decryption Server: Similar to an encryption server, a decryption server is responsible for
converting ciphertext back to plaintext using the appropriate secret key. It uses the same
secret key that was used for encryption (in the case of AES, which is symmetric encryption) to
reverse the encryption process.
 Receiver: This is the entity that receives the encrypted data (ciphertext). The receiver is
responsible for decrypting the ciphertext back into plaintext using the secret key.

Example to Understand AES Algorithm in ASP.NET Core Web API:


Let us understand how to implement Encryption and Decryption using AES Algorithm to secure our
services. We will create two applications. One ASP.NET Core Web API application which expose the
endpoints. Another Console application which will consume the API Endpoints. But here, we need to
transfer the data (Both Request Body and Response Body) in ciphertext, i.e., in encrypted format.

Creating Server Application:


Implementing AES encryption and decryption in an ASP.NET Core Web API involves several steps,
including creating the encryption service, configuring API to use this service, and then applying the
encryption and decryption methods where needed.

First create a new ASP.NET Core Web API Project named AESServerAPP. Then create a folder
named Models within the Project root directory.

Define a Key Storage Service


Create a service to manage keys and IVs of the Clients. This service will be responsible for retrieving
the correct key and IV based on the client ID. So, create a class file named
KeyManagementService.cs and then copy and paste the following code. Here, we have hardcoded
the client details, but in real-time, you will get the same from the database.
namespace AESServerAPP.Models
{
public class KeyManagementService
{
public static List<ClientKeyIV> listKeyIvs = new List<ClientKeyIV>()
{
new ClientKeyIV(){ClientId = "DefaultClient", Key =
"Yyj9nVLtBLwPANTqZNFHrofcH/AbvJlaUbytoHT8Qd8=", IV="/X9EAc4vBALd31ye7N3L1g=="},
new ClientKeyIV(){ClientId = "Client1", Key =
"gi1D2eDd8Tg565ZbfRWc00j9xKtBka4ZHu0Sen+Drgc=",
IV="Qb4nTgWS7UBo2YU7G/gJCg=="},
new ClientKeyIV(){ClientId = "Client2", Key =
"mPjeDLj4jq5AnX/0WeDXBewm05AIOqbV83MfNTWap7A=",
IV="3Y/S5SC3qFNaSbfSKEKxxA=="},
new ClientKeyIV(){ClientId = "Client3", Key =
"J0N55pEAha+B0Oyggc4zWV1GE9iWiW/m7W5DuUo0W3M=",
IV="8PiYfRaj4e5JumnpLh0FzA=="},
};

public static ClientKeyIV? GetKeyAndIV(string clientId)


{
return listKeyIvs.FirstOrDefault(i => i.ClientId.ToLower() == clientId.ToLower());
}
}

public class ClientKeyIV


{
public string ClientId { get; set; }
public string Key { get; set; }
public string IV { get; set; }
}
}

Create a Service for AES Encryption and Decryption:


Next, we need to create a service for managing the Encryption and Decryption using AES Algorithm.
So, create a class file named AesEncryptionService.cs and then copy and paste the following code:
using System.Security.Cryptography;

namespace AESServerAPP.Models
{
public class AesEncryptionService
{
// Method to encrypt a plaintext string using AES encryption with a client-specific key and
IV.
public static string EncryptString(string clientId, string plainText)
{
// Retrieve the AES key and IV using the clientId from a key management service.
var client = KeyManagementService.GetKeyAndIV(clientId);

// Throw an exception if no client configuration is found (invalid clientId).


if (client == null)
throw new Exception("Invalid Client Id");

// Convert the base64-encoded key to a byte array.


byte[] _key = Convert.FromBase64String(client.Key);

// Convert the base64-encoded IV to a byte array.


byte[] _iv = Convert.FromBase64String(client.IV);

// Create a new instance of the AES algorithm.


using (var aesAlg = Aes.Create())
{
// Set the key for the AES algorithm.
aesAlg.Key = _key;
// Set the IV for the AES algorithm.
aesAlg.IV = _iv;

// Create an encryptor from the AES instance to encrypt data.


var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// MemoryStream is used to hold the encrypted bytes.
using (var msEncrypt = new MemoryStream())
{
// CryptoStream for cryptographic transformation of data.
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor,
CryptoStreamMode.Write))
// StreamWriter to write the plaintext to the stream in a particular encoding.
using (var swEncrypt = new StreamWriter(csEncrypt))
{
// Write the plaintext to the crypto stream to perform encryption.
swEncrypt.Write(plainText);
}
// Convert the encrypted bytes from the memory stream to a base64 string.
return Convert.ToBase64String(msEncrypt.ToArray());
}
}
}

// Method to decrypt a ciphertext string using AES decryption with a client-specific key
and IV.
public static string DecryptString(string clientId, string cipherText)
{
// Retrieve the AES key and IV using the clientId from a key management service.
var client = KeyManagementService.GetKeyAndIV(clientId);

// Throw an exception if no client configuration is found (invalid clientId).


if (client == null)
throw new Exception("Invalid Client Id");

// Convert the base64-encoded key to a byte array.


byte[] _key = Convert.FromBase64String(client.Key);
// Convert the base64-encoded IV to a byte array.
byte[] _iv = Convert.FromBase64String(client.IV);

// Convert the base64-encoded ciphertext into a byte array.


var buffer = Convert.FromBase64String(cipherText);

// Create a new instance of the AES algorithm.


using (var aesAlg = Aes.Create())
{
// Set the key for the AES algorithm.
aesAlg.Key = _key;
// Set the IV for the AES algorithm.
aesAlg.IV = _iv;

// Create a decryptor from the AES instance to decrypt data.


var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// MemoryStream is used to read the encrypted bytes.
using (var msDecrypt = new MemoryStream(buffer))
{
// CryptoStream for cryptographic transformation of data.
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor,
CryptoStreamMode.Read))
// StreamReader to read the decrypted plaintext from the stream.
using (var srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted text from the crypto stream and return it.
return srDecrypt.ReadToEnd();
}
}
}
}
}
}

EncryptString Method:
This method is used to encrypt a given plaintext string using the Advanced Encryption Standard (AES)
algorithm. It uses a client-specific key and initialization vector (IV) for encryption, which are obtained
from a key management service using the client's ID. The method ensures secure encryption of
sensitive data, returning the encrypted data as a base64 encoded string, suitable for safe
transmission.
DecryptString Method:
This method is used to decrypt a previously encrypted base64 encoded string (ciphertext) using the
AES algorithm. Similar to the encryption process, it retrieves the client-specific AES key and IV. This
method allows the recovery of the original plaintext from the ciphertext, assuming that the correct key
and IV are used, which are important for maintaining the integrity and confidentiality of the data.

Creating Employee Model:


Next, we need to Create the Employee model which will hold the data in memory. So, within the
Models folder, create a class file named Employee.cs and then copy and paste the following code:
namespace AESServerAPP.Models
{
public class Employee
{
public int? Id { get; set; }
public string Name { get; set; }
public decimal Salary { get; set; }
}
}

EmployeesController:
Next, create the EmployeesController to perform the database CRUD operations using the Employee
model. Here, the action method will receive the input data in encrypted format and also the action
method returns the response data in encrypted format. So, create an API Empty Controller named
EmployeesController within the Controllers folder and then copy and paste the following code. The
following code is self-explained, so please go through the comment lines.
using AESServerAPP.Models;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;

namespace AESServerAPP.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class EmployeesController : ControllerBase
{
// Static list to act as our database.
private static List<Employee> _employees = new List<Employee>
{
new Employee { Id = 1, Name = "Alice Smith", Salary = 75000 },
new Employee { Id = 2, Name = "Bob Johnson", Salary = 60000 },
new Employee { Id = 3, Name = "Carol White", Salary = 55000 }
};

// Endpoint to get all employees, results are encrypted.


[HttpGet]
public ActionResult<IEnumerable<string>> GetEmployees()
{
// Extract 'ClientId' from request headers or use 'DefaultClient' if not present.
var clientId = Request.Headers["ClientId"].FirstOrDefault() ?? "DefaultClient";
// Serialize and encrypt the list of employees using AES.
var encryptedEmployees = AesEncryptionService.EncryptString(clientId,
JsonSerializer.Serialize(_employees));

// Return the encrypted string as a successful result.


return Ok(encryptedEmployees);
}

// Endpoint to get a single employee by ID, result is encrypted.


[HttpGet("{id}")]
public ActionResult<string> GetEmployee(int id)
{
// Extract 'ClientId' from request headers or use 'DefaultClient' if not present.
var clientId = Request.Headers["ClientId"].FirstOrDefault() ?? "DefaultClient";
// Find the employee by ID.
var employee = _employees.FirstOrDefault(e => e.Id == id);
if (employee == null)
{
return NotFound();
}
// Serialize and encrypt the employee's data.
var encryptedEmployee = AesEncryptionService.EncryptString(clientId,
JsonSerializer.Serialize(employee));
return Ok(encryptedEmployee);
}

// Endpoint to add a new employee, input and output are encrypted.


[HttpPost]
public ActionResult<string> PostEmployee([FromBody] string encryptedEmployee)
{
// Extract 'ClientId' from request headers or use 'DefaultClient' if not present.
var clientId = Request.Headers["ClientId"].FirstOrDefault() ?? "DefaultClient";
// Decrypt and deserialize the employee data from the request.
var decryptedEmployee =
JsonSerializer.Deserialize<Employee>(AesEncryptionService.DecryptString(clientId,
encryptedEmployee));
if (decryptedEmployee == null)
{
return BadRequest("Invalid employee data");
}
// Assign a new ID to the employee and add them to the list.
decryptedEmployee.Id = _employees.Max(e => e.Id) + 1;
_employees.Add(decryptedEmployee);
// Encrypt and serialize the new employee's data to send back.
var encryptedResponse = AesEncryptionService.EncryptString(clientId,
JsonSerializer.Serialize(decryptedEmployee));
return CreatedAtAction("GetEmployee", new { id = decryptedEmployee.Id },
encryptedResponse);
}

// Endpoint to update an existing employee, input is encrypted.


[HttpPut("{id}")]
public IActionResult PutEmployee(int id, [FromBody] string encryptedEmployee)
{
// Extract 'ClientId' from request headers or use 'DefaultClient' if not present.
var clientId = Request.Headers["ClientId"].FirstOrDefault() ?? "DefaultClient";
// Decrypt and deserialize the incoming employee data.
var decryptedEmployee =
JsonSerializer.Deserialize<Employee>(AesEncryptionService.DecryptString(clientId,
encryptedEmployee));
var existingEmployee = _employees.FirstOrDefault(e => e.Id == id);
if (existingEmployee == null)
{
return NotFound();
}
// Update the existing employee's details.
existingEmployee.Name = decryptedEmployee.Name;
existingEmployee.Salary = decryptedEmployee.Salary;
return NoContent();
}
// Endpoint to delete an employee by ID.
[HttpDelete("{id}")]
public IActionResult DeleteEmployee(int id)
{
var employee = _employees.FirstOrDefault(e => e.Id == id);
if (employee == null)
{
return NotFound();
}
// Remove the employee from the list.
_employees.Remove(employee);
return NoContent();
}
}
}

AESClientAPP
Next, we need to create the Client APP consuming the service with AES encryption and decryption.
For this, we are going to create a Console Application. So, create a Console Application named
AESClientAPP. Once you create the Console Application, modify the Program class code as follows:
using System.Security.Cryptography;
using System.Text.Json;
using System.Text;

namespace AESClientAPP
{
public class Program
{
// Base URL of the API server.
private static readonly string BaseUrl = "https://localhost:7029/api/Employees"; // Base
API URL
private static readonly string ClientId = "Client1"; // Client identifier for AES encryption
private static readonly string Key =
"gi1D2eDd8Tg565ZbfRWc00j9xKtBka4ZHu0Sen+Drgc="; // Base64-encoded AES key
private static readonly string IV = "Qb4nTgWS7UBo2YU7G/gJCg=="; // Base64-encoded
AES IV

// Asynchronous main function.


static async Task Main(string[] args)
{
// HttpClient is used to make HTTP requests.
using (HttpClient client = new HttpClient())
{
// Add the ClientId to the default request headers.
client.DefaultRequestHeaders.Add("ClientId", ClientId);

try
{
// Fetching all employees data.
Console.WriteLine("Fetching all employees...");
HttpRequestMessage getAllRequest = new HttpRequestMessage(HttpMethod.Get,
BaseUrl);
HttpResponseMessage getAllResponse = await client.SendAsync(getAllRequest);
string encryptedGetAllResponse = await
getAllResponse.Content.ReadAsStringAsync();
string decryptedGetAllResponse = DecryptString(encryptedGetAllResponse);
Console.WriteLine("Decrypted response (All Employees):");
Console.WriteLine(decryptedGetAllResponse);
List<Employee> employees =
JsonSerializer.Deserialize<List<Employee>>(decryptedGetAllResponse);
foreach (var emp in employees)
{
Console.WriteLine($"Employee Details - ID: {emp.Id}, Name: {emp.Name},
Salary: {emp.Salary}");
}

// Fetching a specific employee by ID.


Console.WriteLine("\nFetching employee with ID 1...");
HttpRequestMessage getOneRequest = new HttpRequestMessage(HttpMethod.Get,
$"{BaseUrl}/1");
HttpResponseMessage getOneResponse = await
client.SendAsync(getOneRequest);
string encryptedGetOneResponse = await
getOneResponse.Content.ReadAsStringAsync();
string decryptedGetOneResponse = DecryptString(encryptedGetOneResponse);
Console.WriteLine("Decrypted response (Employee ID 1):");
Console.WriteLine(decryptedGetOneResponse);
Employee employee =
JsonSerializer.Deserialize<Employee>(decryptedGetOneResponse);
Console.WriteLine($"Employee Details - ID: {employee.Id}, Name:
{employee.Name}, Salary: {employee.Salary}");

// Adding a new employee.


Console.WriteLine("\nAdding a new employee...");
var newEmployee = new Employee { Name = "David Brown", Salary = 65000 };
var encryptedEmployee = EncryptString(JsonSerializer.Serialize(newEmployee));
string jsonPayload = $"\"{encryptedEmployee}\"";
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
HttpRequestMessage postRequest = new HttpRequestMessage(HttpMethod.Post,
BaseUrl) { Content = content };
HttpResponseMessage postResponse = await client.SendAsync(postRequest);
string encryptedPostResponse = await
postResponse.Content.ReadAsStringAsync();
string decryptedPostResponse = DecryptString(encryptedPostResponse);
Console.WriteLine("Decrypted response (New Employee):");
Console.WriteLine(decryptedPostResponse);

// Updating an existing employee.


Console.WriteLine("\nUpdating employee with ID 1...");
var updatedEmployee = new Employee { Name = "David Brown Updated", Salary =
70000 };
encryptedEmployee = EncryptString(JsonSerializer.Serialize(updatedEmployee));
jsonPayload = $"\"{encryptedEmployee}\"";
content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
HttpRequestMessage putRequest = new HttpRequestMessage(HttpMethod.Put,
$"{BaseUrl}/1") { Content = content };
HttpResponseMessage putResponse = await client.SendAsync(putRequest);
Console.WriteLine(putResponse.IsSuccessStatusCode ? "Update successful" :
"Update failed");

// Deleting an employee.
Console.WriteLine("\nDeleting employee with ID 2...");
HttpRequestMessage deleteRequest = new
HttpRequestMessage(HttpMethod.Delete, $"{BaseUrl}/2");
HttpResponseMessage deleteResponse = await client.SendAsync(deleteRequest);
Console.WriteLine(deleteResponse.IsSuccessStatusCode ? "Deletion
successful" : "Deletion failed");
}
catch (Exception ex)
{
// Handle and report any errors that occur during the HTTP requests.
Console.WriteLine($"Error: {ex.Message}");
}
}

// Wait for a key press before closing the console window.


Console.ReadKey();
}

// Encrypts a plaintext string using AES and returns the base64-encoded cipher text.
private static string EncryptString(string plainText)
{
// Convert the base64-encoded key into a byte array.
byte[] _key = Convert.FromBase64String(Key);

// Convert the base64-encoded IV into a byte array.


byte[] _iv = Convert.FromBase64String(IV);

// Create a new AES instance to perform the symmetric algorithm.


using (var aesAlg = Aes.Create())
{
// Assign the encryption key to the AES algorithm.
aesAlg.Key = _key;

// Assign the initialization vector to the AES algorithm.


aesAlg.IV = _iv;

// Create an encryptor object to transform the data.


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

// Create a memory stream to hold the encrypted data.


using (var msEncrypt = new MemoryStream())
{
// Create a cryptographic stream that encrypts data and writes it to the memory
stream.
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor,
CryptoStreamMode.Write))
{
// Create a stream writer to write the plain text data to the crypto stream.
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
// Convert the encrypted data from the memory stream to a base64 string.
return Convert.ToBase64String(msEncrypt.ToArray());
}
}
}
}

// Decrypts a base64-encoded cipher text string using AES and returns the plaintext.
private static string DecryptString(string cipherText)
{
// Convert the base64-encoded key into a byte array.
byte[] _key = Convert.FromBase64String(Key);

// Convert the base64-encoded IV into a byte array.


byte[] _iv = Convert.FromBase64String(IV);
// Convert the base64-encoded cipher text into a byte array.
var buffer = Convert.FromBase64String(cipherText);

// Create a new AES instance to perform the symmetric algorithm.


using (var aesAlg = Aes.Create())
{
// Assign the decryption key to the AES algorithm.
aesAlg.Key = _key;

// Assign the initialization vector to the AES algorithm.


aesAlg.IV = _iv;

// Create a decryptor object to transform the encrypted data back into plain text.
var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

// Create a memory stream to read the encrypted data.


using (var msDecrypt = new MemoryStream(buffer))
{
// Create a cryptographic stream that reads and decrypts data from the memory
stream.
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor,
CryptoStreamMode.Read))
{
// Create a stream reader to read the decrypted plain text data from the crypto
stream.
using (var srDecrypt = new StreamReader(csDecrypt))
{
// Return the decrypted text read from the stream reader.
return srDecrypt.ReadToEnd();
}
}
}
}
}

// Definition of the Employee class used to serialize and deserialize employee data.
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Salary { get; set; }
}
}
}

Now, first run the ASP.NET Core Web API Project and then run the Console Application and you
should see the output as expected as shown in the below image.
Key Generator Console Application:
Now, create a new Console Application for generating the Valid Key and IV. So, create a Dot Net
Console Application named KeyGeneratorService. Then modify the Program class as follows. The
following code is self-explained, so please go through the comment line for a better understanding.
using System.Security.Cryptography;

namespace KeyGeneratorService
{
// Main class of the KeyGeneratorService program
public class Program
{
// Entry point of the console application
static void Main(string[] args)
{
// Call the method to generate AES key and IV
GenerateAesKeyAndIV();
// Wait for a key press to prevent the console from closing immediately
Console.ReadKey();
}

// Method to generate an AES key and Initialization Vector (IV)


private static void GenerateAesKeyAndIV()
{
// Create a new AES object to generate keys.
// 'using' statement ensures that the AES instance is disposed correctly
using (Aes aesAlg = Aes.Create())
{
// Set the size of the encryption key to 256 bits, offering strong security
aesAlg.KeySize = 256;

// Generate a random key based on the key size set above


aesAlg.GenerateKey();

// Generate a random initialization vector (IV)


aesAlg.GenerateIV();

// Convert the generated key to a base64 string for easier readability and storage
string key = Convert.ToBase64String(aesAlg.Key);

// Convert the generated IV to a base64 string for easier readability and storage
string iv = Convert.ToBase64String(aesAlg.IV);

// Output the base64-encoded AES key to the console


Console.WriteLine("AES Key (Base64): " + key);

// Output the base64-encoded AES IV to the console


Console.WriteLine("AES IV (Base64): " + iv);
}
}
}
}
Why Encryption and Decryption in ASP.NET Core Web API?
Encryption and Decryption are important security features in any web application, including those built
using ASP.NET Core Web API. The following are the reasons why Encryption and Decryption are
important in Web Application:
 Protecting Sensitive Data: Encryption helps protect sensitive data such as personal user
information, payment details, and confidential business data. By encrypting data, it becomes
unreadable to unauthorized users. Even if an attacker manages to intercept the data, without
the proper decryption key, the information remains useless.
 Ensuring Data Integrity: Encryption ensures that data has not been altered in transit. This
helps in maintaining data integrity, making sure that the data sent is exactly what is received
on the other end.
 Meeting Compliance Requirements: Many industries are governed by regulatory standards
that require the protection of sensitive data. For example, the Health Insurance Portability and
Accountability Act (HIPAA) in healthcare, the Payment Card Industry Data Security Standard
(PCI DSS) for payment data, and the General Data Protection Regulation (GDPR) in the EU.
Encryption helps in complying with these regulations.
 Securing Communication: When using a Web API, data is frequently transmitted over the
internet. Encryption ensures that this data is protected during transmission.
 Building Trust: Implementing robust security measures, including encryption, helps build
trust with your users. They are more likely to trust your application with their personal and
sensitive information if they know it is secured.

What are MemoryStream, CryptoStream, StreamWriter, and StreamReader Objects?


The classes MemoryStream, CryptoStream, StreamWriter in Encryption and StreamReader in
Decryption are used together to handle the encryption and decryption of data with AES. Let us have a
look at each of these classes:

MemoryStream
MemoryStream is a stream that stores data in memory as bytes. It doesn't require a backing store like
a file, making it fast and flexible for scenarios where temporary storage is needed.
 Usage in Encryption: In EncryptString method, a MemoryStream instance is used to hold
the encrypted bytes as they are processed. This is convenient because we can dynamically
write data as it is encrypted and then easily convert the entire content to a byte array or
base64 string afterwards.
 Usage in Decryption: In the DecryptString method, MemoryStream is initialized with the byte
array that represents the encrypted data (converted from base64). This allows the
CryptoStream to read from this buffer directly to perform decryption.

CryptoStream
CryptoStream provides a way to link data streams to cryptographic transformations. It can be used for
both encrypting and decrypting data, depending on how it is set up.
 Usage in Encryption: In the EncryptString method, the CryptoStream is linked to the
MemoryStream and set up with an encryptor object (aesAlg.CreateEncryptor()). As data is
written to this stream, it is automatically encrypted using the specified AES key and IV, and
then passed to the memory stream.
 Usage in Decryption: In the DecryptString method, CryptoStream is set up with a decryptor
object (aesAlg.CreateDecryptor()). It reads from a MemoryStream containing the encrypted
data and decrypts it as the data is being read.
StreamWriter:
StreamWriter is used to write characters to a stream in a specific encoding (by default, UTF-8). In the
EncryptString method, StreamWriter is used to write the plaintext string to the CryptoStream. This
converts the plaintext string into a byte stream in a specified encoding and passes it through the
encryption process implemented in CryptoStream.

StreamReader:
Conversely, StreamReader is used to read characters from a byte stream into a string. In the
DecryptString method, StreamReader reads the decrypted byte stream from the CryptoStream and
converts it back into a readable string (the original plaintext).

How They Work Together


In both methods, these streams are layered together to handle the data transformation seamlessly:
 For encryption: StreamWriter -> CryptoStream -> MemoryStream
 For decryption: MemoryStream -> CryptoStream -> StreamReader

You might also like