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
Learn how to manage recurring payments on Google Pay
Digitizing Customer Experience - An In-Depth Guide
St Thomas Usvi Craigslist
Skyward Houston County
855-392-7812
Tv Guide Bay Area No Cable
Walgreens Alma School And Dynamite
What is international trade and explain its types?
Apnetv.con
Slapstick Sound Effect Crossword
Steve Strange - From Punk To New Romantic
Red Heeler Dog Breed Info, Pictures, Facts, Puppy Price & FAQs
Craiglist Galveston
Who called you from 6466062860 (+16466062860) ?
Trivago Sf
Invitation Homes plans to spend $1 billion buying houses in an already overheated market. Here's its presentation to investors setting out its playbook.
Bekijk ons gevarieerde aanbod occasions in Oss.
Phoebus uses last-second touchdown to stun Salem for Class 4 football title
Qhc Learning
The EyeDoctors Optometrists, 1835 NW Topeka Blvd, Topeka, KS 66608, US - MapQuest
About My Father Showtimes Near Copper Creek 9
Jobs Hiring Near Me Part Time For 15 Year Olds
What Is The Lineup For Nascar Race Today
Die 8 Rollen einer Führungskraft
Villano Antillano Desnuda
'Insidious: The Red Door': Release Date, Cast, Trailer, and What to Expect
Jurassic World Exhibition Discount Code
Craigslist Boerne Tx
Brenda Song Wikifeet
Swgoh Boba Fett Counter
P3P Orthrus With Dodge Slash
Southern Democrat vs. MAGA Republican: Why NC governor race is a defining contest for 2024
Golden Tickets
Slv Fed Routing Number
ShadowCat - Forestry Mulching, Land Clearing, Bush Hog, Brush, Bobcat - farm & garden services - craigslist
Indiana Wesleyan Transcripts
Tmka-19829
Dmitri Wartranslated
Spectrum Outage in Genoa City, Wisconsin
Academy Sports New Bern Nc Coupons
Torrid Rn Number Lookup
Best Restaurants West Bend
Sand Castle Parents Guide
Anthem Bcbs Otc Catalog 2022
Conan Exiles Colored Crystal
Yosemite Sam Hood Ornament
Smoke From Street Outlaws Net Worth
Wwba Baseball
Electronics coupons, offers & promotions | The Los Angeles Times
Southern Blotting: Principle, Steps, Applications | Microbe Online
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.