Encrypting and Decrypting a String in C# - Code Maze (2024)

Posted by Code Maze | Updated Date Jan 14, 2023 | 2

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API programand learn how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials (Security book, Docker book, and other bonus files) are included in the Premium package!

In this article, we will learn how encrypting and decrypting a string is done using C# and the Cryptography package that comes included with .NET.

To download the source code for this article, you can visit our GitHub repository.

Let’s start.

Types of Encryption Algorithms

We use encryption to obscure a piece of information, for example, a text, turning it into a series of seemingly random bytes. When storing encrypted data or sending it to a recipient, third parties will be unable to make sense of the encrypted information if someone other than the intended recipient gains access to the information.

We can categorize different encryption algorithms into three main groups: Symmetric or secret key encryption algorithms, which use a single secret password, or key, that we need to share with the recipients of the information so they can decrypt it and gain access to the original message.

On the other hand, Asymmetric or public key encryption is based on public/private key pairs. We are more secure since there’s no secret shared key that we need to transmit and hackers can, potentially, intercept.

Finally, Hashing algorithms provide one-way encryption. These are used, among other things, for digital signing and password protection.

For this article, we will focus on a symmetric encryption algorithm that uses a shared secret key.

Encrypting and Decrypting in C#

We will be using System.Security.Cryptography, a package included in .NET. This package bundles several tools for encryption and decryption including implementations of various algorithms.

Choosing the Right Algorithm for Encrypting and Decrypting a String

Among all supported symmetric-key algorithms, the HMACSHA256 and its variants are only suitable for data verification and cryptographic document signing. That leaves us with AES encryption as our only choice for secret key data protection.

AES stands for “Advanced Encryption Standard” and it is an official international standard (ISO/IEC 18033-3) for symmetric-key encryption. Considering all this, we are going to base our example on the AES algorithm implementation.

Encrypting and Decrypting a String With AES

Using the .NET cryptography package to encrypt a simple string value is not straightforward. We will have to deal with byte arrays, streams, disposable objects, etc. Therefore, for our example, we will try to hide all that complexity into a single class called StringEncryptionService with an easy-to-use interface.

Encryption Key and Initialization Vector

We aim to implement an encryption method that takes a string and a passphrase as input parameters. We will have to use the same passphrase to turn that encrypted data back to its unencrypted version.

The AES encryption algorithm uses the concept of an encryption key used to encrypt and decrypt the data. That aligns with the use we want to make of a user-provided passphrase.

However, we can’t use the passphrase directly since the AES encryption key needs to be either 128, 192, or, 256 bits long. The accepted key length depends on the value of the BlockSize property of the Aes object instance.

To solve that, we will implement a private method in our StringEncryptionService class to transform the user-provided password into a valid encryption key:

private byte[] DeriveKeyFromPassword(string password){ var emptySalt = Array.Empty<byte>(); var iterations = 1000; var desiredKeyLength = 16; // 16 bytes equal 128 bits. var hashMethod = HashAlgorithmName.SHA384; return Rfc2898DeriveBytes.Pbkdf2(Encoding.Unicode.GetBytes(password), emptySalt, iterations, hashMethod, desiredKeyLength);}

Here, we are using a key derivation algorithm called PBKDF2 to turn the user passphrase into a random fixed-length byte array. To achieve this we are using the static method Rfc2898DeriveBytes.Pbkdf2(). Note that we could potentially use a password salt as the second parameter of this call. In this case, however, we are just using an empty salt for simplicity.

Likewise, the AES implementation requires an initialization vector. We will use a 128-bit value called initialization vector or IV to generate more entropy in the resulting encrypted data. This will make it more difficult to identify patterns in it.

Again, for simplicity and because we are dealing with relatively small string values we will use a fixed IV:

private byte[] IV ={ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};

If we do not provide values for the encryption key and/or the initialization vector AES will generate random values for us. But, in that case, we must store both values somewhere since we will need them to decrypt our data later.

String Encryption Method

Now that we have our IV and a way to generate valid encryption keys, we can proceed to implement our string encryption method:

public async Task<byte[]> EncryptAsync(string clearText, string passphrase){ using Aes aes = Aes.Create(); aes.Key = DeriveKeyFromPassword(passphrase); aes.IV = IV; using MemoryStream output = new(); using CryptoStream cryptoStream = new(output, aes.CreateEncryptor(), CryptoStreamMode.Write); await cryptoStream.WriteAsync(Encoding.Unicode.GetBytes(clearText)); await cryptoStream.FlushFinalBlockAsync(); return output.ToArray();}

First, we use the Aes.Create() factory method to obtain an instance of the Aes object that we will later use to obtain an encryptor. We generate our encryption key using the DeriveKeyFromPassword() method discussed earlier and add it to the aes object along with our fixed initialization vector.

Next, we go on and create an output MemoryStream that receives the encrypted data as it gets generated. We also need a CryptoStream wrapping the output stream. Here, we are setting up the CryptoStream with an encryptor and CryptoStreamMode.Write so we can write our input text to it and get encrypted data written to the output stream.

Finally, we write the user-provider clear text to the CryptoStream using the WriteAsync() method. It is important to manually call the FlushFinalBlockAsync() on the cryptoStream object method so all the remaining bytes are written to the output stream before we return its contents.

String Decryption Method

To continue, our decryption method will follow a similar pattern:

public async Task<string> DecryptAsync(byte[] encrypted, string passphrase){ using Aes aes = Aes.Create(); aes.Key = DeriveKeyFromPassword(passphrase); aes.IV = IV; using MemoryStream input = new(encrypted); using CryptoStream cryptoStream = new(input, aes.CreateDecryptor(), CryptoStreamMode.Read); using MemoryStream output = new(); await cryptoStream.CopyToAsync(output); return Encoding.Unicode.GetString(output.ToArray());}

Just like in our Encrypt() method, we set up the encryption key and IV. It is important to use the same values used during encryption to decrypt successfully.

Then, we set up our CryptoStream, this time, wrapped around a MemoryStream containing the encrypted data. Since this is a decryption operation, we use a decryptor instead of an encryptor and CryptoStreamMode.Read.

Finally, we use CryptoStream.CopyToAsync() to copy the contents of cryptoStream into a newly created MemoryStream. At this point, the encrypted data gets pulled from the input MemoryStream and put through the decrypt transformation.

Testing Encryption and Decryption With AES

Now that we have completed the implementation of our StringEncryptionService class, we can use the EncryptAsync() method to turn any text into a password-protected encrypted byte array:

var encryptionService = new StringEncryptionService();const string passphrase = "Sup3rS3curePass!";var encrypted = await encryptionService.EncryptAsync("We use encryption to obscure a piece of information.", passphrase);Console.WriteLine($"Encrypted data: {BitConverter.ToString(encrypted)}");

Upon execution, the previous code should output the generated encrypted bytes:

Encrypted data: 3A-BB-65-D7-50-A9-13-75-D4-96-1F-2A-A3-02-97-A6-51-EA...

In the same fashion, we can use the DecryptAsync() method along with the original password to decrypt those bytes and get the original text back:

var decrypted = await encryptionService.DecryptAsync(encrypted, passphrase);Console.WriteLine($"Decrypted data: {decrypted}");

The output for this code should return the original text:

Decrypted data: We use encryption to obscure a piece of information.

Conclusion

In this article, we have learned about the different types of encryption algorithms. We talked about the cryptography package in .NET. We also have created a simple class with methods for encrypting and decrypting a string using the symmetric secret-key algorithm AES.

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API programand learn how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials (Security book, Docker book, and other bonus files) are included in the Premium package!

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!

Encrypting and Decrypting a String in C# - Code Maze (2024)
Top Articles
Biggest Real Estate Agencies In California - ArchVisualizations
Scale AI Cofounder Alexandr Wang Regains World’s Youngest Self-Made Billionaire Title
Po Box 7250 Sioux Falls Sd
The Largest Banks - ​​How to Transfer Money With Only Card Number and CVV (2024)
Avonlea Havanese
Tesla Supercharger La Crosse Photos
Obituary (Binghamton Press & Sun-Bulletin): Tully Area Historical Society
Best Theia Builds (Talent | Skill Order | Pairing + Pets) In Call of Dragons - AllClash
Barstool Sports Gif
Acbl Homeport
Azeroth Pilot Reloaded - Addons - World of Warcraft
Bros Movie Wiki
Springfield Mo Craiglist
Love In The Air Ep 9 Eng Sub Dailymotion
Midlife Crisis F95Zone
Craftology East Peoria Il
Eva Mastromatteo Erie Pa
Mzinchaleft
Palm Coast Permits Online
NHS England » Winter and H2 priorities
Bj Alex Mangabuddy
Unity - Manual: Scene view navigation
Governor Brown Signs Legislation Supporting California Legislative Women's Caucus Priorities
Hampton University Ministers Conference Registration
Jordan Poyer Wiki
How to Make Ghee - How We Flourish
Walmart Pharmacy Near Me Open
Beaufort 72 Hour
Kroger Feed Login
4Oxfun
JVID Rina sauce set1
Marokko houdt honderden mensen tegen die illegaal grens met Spaanse stad Ceuta wilden oversteken
Ou Football Brainiacs
Miles City Montana Craigslist
Angel Haynes Dropbox
Publix Christmas Dinner 2022
Craftsman Yt3000 Oil Capacity
Motor Mounts
Kamzz Llc
4083519708
Second Chance Apartments, 2nd Chance Apartments Locators for Bad Credit
6576771660
Here's Everything You Need to Know About Baby Ariel
Lady Nagant Funko Pop
Port Huron Newspaper
Crigslist Tucson
Devotion Showtimes Near Showplace Icon At Valley Fair
552 Bus Schedule To Atlantic City
Diccionario De Los Sueños Misabueso
Sam's Club Fountain Valley Gas Prices
Latest Posts
Article information

Author: Golda Nolan II

Last Updated:

Views: 6335

Rating: 4.8 / 5 (58 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Golda Nolan II

Birthday: 1998-05-14

Address: Suite 369 9754 Roberts Pines, West Benitaburgh, NM 69180-7958

Phone: +522993866487

Job: Sales Executive

Hobby: Worldbuilding, Shopping, Quilting, Cooking, Homebrewing, Leather crafting, Pet

Introduction: My name is Golda Nolan II, I am a thoughtful, clever, cute, jolly, brave, powerful, splendid person who loves writing and wants to share my knowledge and understanding with you.