Encryption and Decryption of a string using AES in C#

AES is a symmetric block cipher algorithm. A private key is used to encrypt and decrypt the message. Encryption of data can be done in various ways.

Why Encryption is needed ? There are fields like DateOfBirth and Aadhar number or SSN which a user don’t want to show to the others and he wants it to be encrypted before being saved to the database.

We are using one master key to encrypt the data. This can be stored on cloud of any config file or in the environment variables. _masterKey variable contains a string key which can be any valid string. This master key must be secrete. We will use the Amazon.KeyManagementService to generate the datakey.

Here is the code to encrypt a string:

First include the below namespaces

using Amazon;
using Amazon.KeyManagementService;
using Amazon.KeyManagementService.Model;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Synergy.Processing.Common.Utilities;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

Below function is to encrypt a string.

public string Encrypt(string data)
{
GenericFunctions.LogInformation(_logger, “Encrypt Method execution started: ” + data);
if (!string.IsNullOrEmpty(data))
{
using (var algorithm = Aes.Create())
{
using (var msEncrypt = new MemoryStream())
{
using (var kmsClient = new AmazonKeyManagementServiceClient(RegionEndpoint.USEast1))
{
GenerateDataKeyResponse dataKey = null;
try
{
GenericFunctions.LogInformation(_logger, “Encrypt Method encryption key: ” + _masterKey);
dataKey = kmsClient.GenerateDataKeyAsync(new GenerateDataKeyRequest
{
KeyId = _masterKey,
KeySpec = DataKeySpec.AES_256,
}).Result;

var cipherTextBlobLength = BitConverter.GetBytes((int) dataKey.CiphertextBlob.Length);
msEncrypt.Write(cipherTextBlobLength, 0, 4);
dataKey.CiphertextBlob.CopyTo(msEncrypt);

algorithm.Key = dataKey.Plaintext.ToArray();
GenericFunctions.LogInformation(_logger, “Encrypt Method algorithm key: ” + algorithm.Key);
msEncrypt.Write(algorithm.IV, 0, algorithm.IV.Length);
}
finally
{
dataKey?.Plaintext?.Dispose();
dataKey?.CiphertextBlob?.Dispose();
}
}
var encryptor = algorithm.CreateEncryptor(algorithm.Key, algorithm.IV);

using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
var dataBytes = Encoding.UTF8.GetBytes(data);

using (var input = new MemoryStream(dataBytes))
{
input.CopyTo(csEncrypt);
csEncrypt.FlushFinalBlock();
}
GenericFunctions.LogInformation(_logger, “Encrypt Method encrypted value: ” + Convert.ToBase64String(msEncrypt.ToArray()));
return Convert.ToBase64String(msEncrypt.ToArray());
}
}
}
}
return null;
}

private MemoryStream DecryptDataKey(MemoryStream ciphertext)
{
using (var kmsClient = new AmazonKeyManagementServiceClient(RegionEndpoint.USEast1))
{
var decryptionResponse = kmsClient.DecryptAsync(new DecryptRequest
{
CiphertextBlob = ciphertext,
}).Result;
return decryptionResponse.Plaintext;
}
}



public string Decrypt(string data)
{
GenericFunctions.LogInformation(_logger, “Decrypt Method execution started: ” + data);
if (!string.IsNullOrEmpty(data))
{
using (var msDecrypt = new MemoryStream(Convert.FromBase64String(data)))
{
var lBytes = new byte[4];
msDecrypt.Read(lBytes, 0, 4);
var length = BitConverter.ToInt32(lBytes, 0);
GenericFunctions.LogInformation(_logger, “Decrypt Method data length: ” + length);
var buffer = new byte[length];
msDecrypt.Read(buffer, 0, length);

using (var dataKeyCipher = DecryptDataKey(new MemoryStream(buffer)))
                {
                    using (var algorithm = Aes.Create())
                    {
                        algorithm.Key = dataKeyCipher.ToArray();

                        var iv = algorithm.IV;
                        msDecrypt.Read(iv, 0, iv.Length);
                        algorithm.IV = iv;

                        var decryptor = algorithm.CreateDecryptor(algorithm.Key, algorithm.IV);

                        using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                        {
                            using (var srDecrypt = new MemoryStream())
                            {
                                csDecrypt.CopyTo(srDecrypt);
                                GenericFunctions.LogInformation(_logger, "Decrypt Method Decrypted value: " + Encoding.UTF8.GetString(srDecrypt.ToArray()));
                                return Encoding.UTF8.GetString(srDecrypt.ToArray());
                            }
                        }
                    }
                }
            }
        }

        return null;
    }


Please post your comments if you find it useful. Here is one tutorial to read basic of cryptography.

Leave a Reply

Your email address will not be published.