Learn how to protect the information handled by your .NET applications by encrypting and decrypting the data using either a single key or a public/private key pair. Credit: Yuri Samoilov Encryption transforms data into a form that can be read only by someone who has a key that allows them to decrypt it. You can use encryption to protect data “at rest” (data that resides in a data store) or to protect data “in motion” (data that is being sent over a network). This article will examine how we can work with two types of encryption in C#, symmetric encryption and asymmetric encryption. Symmetric encryption uses one key for both encryption and decryption. Asymmetric encryption uses two distinct keys for encryption and decryption. To work with the code examples provided in this article, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download a copy from here. Create a .NET Core console application project in Visual Studio First off, let’s create a .NET Core console application project in Visual Studio 2022. Assuming Visual Studio 2022 is installed in your system, follow the steps outlined below to create a new .NET Core console application project. Launch the Visual Studio 2022 Preview IDE. Click on “Create new project.” In the “Create new project” window, select “Console App (.NET Core)” from the list of templates displayed. Click Next. In the “Configure your new project” window shown next, specify the name and location for the new project. Click Next. In the “Additional information” window, specify .NET 7 as the .NET version you would like to use. Click Create. This will create a new .NET 7 console application project in Visual Studio 2022. We’ll use this project to work with encryption in the subsequent sections of this article. Symmetric encryption vs. asymmetric encryption Encryption is of two types: symmetric encryption and asymmetric encryption. Both symmetric and asymmetric encryption can help protect sensitive data residing in your data store or in transit. C# provides built-in support for symmetric and asymmetric encryption through the System.Security.Cryptography namespace. Whereas symmetric encryption uses only one key for encrypting and decrypting data, asymmetric encryption uses two keys: a public key used for encrypting the data and a private key used for decrypting the data. Symmetric encryption is generally faster and more efficient, but you must keep the key secret, because anyone with access to the key can decrypt the data. Asymmetric encryption is slower than symmetric encryption, but it’s also much more secure because the decryption key is not shared. Only the person possessing the private key will be able to decode the data. The differences between symmetric and asymmetric encryption make them suitable for different use cases, as Microsoft points out here in the .NET documentation: Symmetric encryption and asymmetric encryption are performed using different processes. Symmetric encryption is performed on streams and is therefore useful to encrypt large amounts of data. Asymmetric encryption is performed on a small number of bytes and is therefore useful only for small amounts of data. This explains why symmetric encryption is often used to protect data sent over the network (such as an email) while asymmetric encryption is often used to protect sensitive data such as social security numbers, passwords, and credit card numbers. In the following sections, we’ll encrypt and decrypt a string using C#, first with symmetric encryption and then with asymmetric encryption. We’ll use a string as the data in our examples to keep things simple. Implementing symmetric encryption in C# To implement symmetric encryption, you will need to generate a 256-bit key for encrypting and decrypting data. Symmetric encryption is faster than asymmetric encryption but less secure because you can use the same key for encrypting and decrypting data. The receiver uses the same shared secret to decrypt the message after receiving it from the sender. If the key is not shared securely, a third party could use it to decrypt and read the data. In the console application project you created earlier, create a static C# class named SymmetricEncryptionDecryptionManager in a file named SymmetricEncryptionDecryptionManager.cs and enter the following code. <code> using System.Security.Cryptography; using System.Text; namespace EncryptionDemo { public class SymmetricEncryptionDecryptionManager { public static string Encrypt(string data, string key) { byte[] initializationVector = Encoding.ASCII.GetBytes("abcede0123456789"); using (Aes aes = Aes.Create()) { aes.Key = Encoding.UTF8.GetBytes(key); aes.IV = initializationVector; var symmetricEncryptor = aes.CreateEncryptor(aes.Key, aes.IV); using (var memoryStream = new MemoryStream()) { using (var cryptoStream = new CryptoStream(memoryStream as Stream, symmetricEncryptor, CryptoStreamMode.Write)) { using (var streamWriter = new StreamWriter(cryptoStream as Stream)) { streamWriter.Write(data); } return Convert.ToBase64String(memoryStream.ToArray()); } } } } public static string Decrypt(string cipherText, string key) { byte[] initializationVector = Encoding.ASCII.GetBytes("abcede0123456789"); byte[] buffer = Convert.FromBase64String(cipherText); using (Aes aes = Aes.Create()) { aes.Key = Encoding.UTF8.GetBytes(key); aes.IV = initializationVector; var decryptor = aes.CreateDecryptor(aes.Key, aes.IV); using (var memoryStream = new MemoryStream(buffer)) { using (var cryptoStream = new CryptoStream(memoryStream as Stream, decryptor, CryptoStreamMode.Read)) { using (var streamReader = new StreamReader(cryptoStream as Stream)) { return streamReader.ReadToEnd(); } } } } } } } </code> In the preceding code listing, notice there are two methods, Encrypt and Decrypt. The Encrypt method accepts the data to encrypt and the secret key as parameters. It leverages the Advanced Encryption Standard (AES) algorithm to perform symmetric data encryption using the secret key. The encrypted data is returned in the form of a Base64 string. The Decrypt method accepts the encrypted data and the secret key as parameters. It converts the cipher text to a byte array, which is used to decrypt the data using the secret key. The decrypted data is returned as a string. You can use the following code snippet to encrypt and decrypt data using the Encrypt and Decrypt methods ofthe SymmetricEncryptionDecryptionManager class. <code> var encryptedText = SymmetricEncryptionDecryptionManager.Encrypt("This is sample text.", key); Console.WriteLine(encryptedText); var decryptedText = SymmetricEncryptionDecryptionManager.Decrypt(encryptedText, key); Console.WriteLine(decryptedText); </code> Implementing asymmetric encryption in C# In asymmetric encryption, two different keys are used to encrypt and decrypt data. The public key is used to encrypt, and the private key is used to decrypt. You must have both a public key and a private key to implement asymmetric encryption. To encrypt data using asymmetric encryption, you first need to generate a public/private key pair. You can do this using the RSA algorithm as shown below. <code> var rsa = new RSACryptoServiceProvider(); string publicKeyXML = rsa.ToXmlString(false); string privateKeyXML = rsa.ToXmlString(true); </code> Once you have generated the key pair, you can use the public key to encrypt data. <code> byte[] data = Encoding.UTF8.GetBytes("Hello world!"); byte[]encryptedData = rsa.Encrypt(data, false); </code> Then, to decrypt the data, you will need to use the private key. <code> byte[] decryptedData = rsa.Decrypt(encryptedData, false); string message = Encoding.UTF8.GetString(decryptedData); </code> Let us create a new class named AsymmetricEncryptionDecryptionManager with the following code. <code> public class AsymmetricEncryptionDecryptionManager { public static string Encrypt(string data, RSAParameters rsaParameters) { using(var rsaCryptoServiceProvider = new RSACryptoServiceProvider()) { rsaCryptoServiceProvider.ImportParameters(rsaParameters); var byteData = Encoding.UTF8.GetBytes(data); var encryptedData = rsaCryptoServiceProvider.Encrypt(byteData, false); return Convert.ToBase64String(encryptedData); } } public static string Decrypt(string cipherText, RSAParameters rsaParameters) { using(var rsaCryptoServiceProvider = new RSACryptoServiceProvider()) { var cipherDataAsByte = Convert.FromBase64String(cipherText); rsaCryptoServiceProvider.ImportParameters(rsaParameters); var encryptedData = rsaCryptoServiceProvider.Decrypt(cipherDataAsByte, false); return Encoding.UTF8.GetString(encryptedData); } } } </code> You can use the following code snippet to encrypt and decrypt data using the Encrypt and Decrypt methods of the AsymmetricEncryptionDecryptionManager class. <code> var rsaCryptoServiceProvider = new RSACryptoServiceProvider(2048); var cipherText = AsymmetricEncryptionDecryptionManager.Encrypt("This is sample text.", rsaCryptoServiceProvider.ExportParameters(false)); Console.WriteLine(cipherText); var plainText = AsymmetricEncryptionDecryptionManager.Decrypt(cipherText, rsaCryptoServiceProvider.ExportParameters(true)); Console.WriteLine(plainText); </code> Figure 1 below shows the output when you execute the above program. IDG Figure 1. A demonstration of asymmetric encryption in .NET. Note that you can merge both SymmetricEncryptionDecryptionManager and AsymmetricEncryptionDecryptionManager into one class and write overloaded methods for symmetric and asymmetric encryption and decryption. You can use this knowledge to build secure applications or websites that protect data from unauthorized access. Related content feature 14 great preprocessors for developers who love to code Sometimes it seems like the rules of programming are designed to make coding a chore. Here are 14 ways preprocessors can help make software development fun again. By Peter Wayner Nov 18, 2024 10 mins Development Tools Software Development feature Designing the APIs that accidentally power businesses Well-designed APIs, even those often-neglected internal APIs, make developers more productive and businesses more agile. By Jean Yang Nov 18, 2024 6 mins APIs Software Development news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks news Go language evolving for future hardware, AI workloads The Go team is working to adapt Go to large multicore systems, the latest hardware instructions, and the needs of developers of large-scale AI systems. By Paul Krill Nov 15, 2024 3 mins Google Go Generative AI Programming Languages Resources Videos