Using Cryptography Classes to Encrypt and Decrypt Data in .NET
Last Updated: Nov 08, 2025
6 min read
Legacy Archive
Legacy Guidance:This article preserves historical web development content. For modern .NET 8+ best practices, visit our Tutorials section.
Cryptography is a way to encrypt and decrypt data. By encrypting data, you're protecting your information from curious users who'd like to know what's stored. Once you encrypt the data, it's in an unreadable form for humans. You'll need to decrypt the data to read it again.
A person who intercepts the encrypted data will find it difficult to decrypt without the proper key. .NET provides a namespace for classes used to encrypt and decrypt data. The System.Security.Cryptography namespace is used for accessing these classes. Classes like AsymmetricAlgorithm, SymmetricAlgorithm, and HashAlgorithm are used for this purpose. These are abstract classes that provide the foundation for encryption operations.
Understanding Cryptographic Primitives
The following are the different types of cryptographic primitives that are used in .NET to encrypt and decrypt data:
Private-key encryption or Symmetric Cryptography: Uses a single shared key to encrypt and decrypt data
Public-key encryption or Asymmetric Cryptography: Uses public/private key pair for encryption operations
Cryptographic Signing: Uses digital signatures to ensure data originates from the intended user
Cryptographic hashes: Maps data from any length to fixed-length byte sequence
Private-key encryption uses a single shared key whereas asymmetric cryptography uses public/private key pairs. Cryptographic signing uses digital signatures that are unique to a particular party. Cryptographic hashes create fixed-length representations of variable-length data.
Available Cryptography Classes
The following classes are provided to implement private-key algorithms: DESCryptoServiceProvider, RC2CryptoServiceProvider, RijndaelManaged, and TripleDESCryptoServiceProvider. For implementing public-key encryption algorithms, DSACryptoServiceProvider and RSACryptoServiceProvider classes are provided. These public-key classes can also be used for cryptographic signing.
Classes like HMACSHA1, MACTripleDES, MD5CryptoServiceProvider, SHA1Managed, SHA256Managed, SHA384Managed, and SHA512Managed are used in cryptographic hashes algorithms and digital signature algorithms.
Implementing Symmetric Cryptography
Symmetric cryptography uses a private key and an initialization vector for processing the encryption of data. You know that encryption is done using a key (or password) that you provide. The intended party also should know that key to decrypt the data.
The initialization vector is used when the mode of encryption is CipherMode.CBC (Cipher Block Chaining). Using this mode, the data is encrypted in blocks. The third block of data is encrypted using the output of the second block, and the second block is encrypted using the output of the first block. If this chaining process happens, what data is used for encrypting the first block? That's where we use an initialization vector to encrypt the first block of data.
EncryptData.vb
Dim crypProvider As SymmetricAlgorithm
Dim mStream As MemoryStream
' Create the encryption provider (RC2 algorithm)
crypProvider = SymmetricAlgorithm.Create("RC2")
mStream = New MemoryStream()
' Create encryptor and crypto stream
Dim crypTrans As ICryptoTransform = crypProvider.CreateEncryptor()
Dim CS As New CryptoStream(mStream, crypTrans, CryptoStreamMode.Write)
' Write data to encrypt
Dim SW As New StreamWriter(CS)
SW.Write(txtData.Text)
SW.Flush()
CS.FlushFinalBlock()
' Get encrypted bytes
Dim mBytes(mStream.Length - 1) As Byte
mStream.Position = 0
mStream.Read(mBytes, 0, mStream.Length)
' Convert to string for display
Dim ENC As New Text.UTF8Encoding()
Dim encData As String = ENC.GetString(mBytes)
MsgBox("Encrypted Data: " & vbCrLf & encData)
The above code encrypts some value entered in a textbox. The code uses the RC2 algorithm, but you can also use any other algorithm like DES or Rijndael. The data entered in a textbox is encrypted upon clicking a button in the form. All the above code is written in the click event of the button. The encrypted data is displayed in a message box.
Decrypting the Data
Once you've encrypted the data, you'll need to decrypt it to read the original content. The decryption process uses the same algorithm and key that were used for encryption.
DecryptData.vb
' Reset stream position
mStream.Position = 0
' Create decryptor
crypTrans = crypProvider.CreateDecryptor()
' Create crypto stream for reading
Dim nCS As New CryptoStream(mStream, crypTrans, CryptoStreamMode.Read)
Dim nSR As New StreamReader(nCS)
' Read decrypted data
Dim dData As String = nSR.ReadToEnd()
MsgBox("Decrypted Data: " & vbCrLf & dData)
The code above is used to decrypt the data that was encrypted. In the above algorithms, we haven't specified any key or initialization vector. This is because .NET uses the default key for encryption. For production applications, you should always specify your own keys.
Using Custom Keys and IVs
For better security, you should specify your own encryption keys and initialization vectors rather than relying on defaults. Here's how to do that:
CustomKeyEncryption.cs
using System.Security.Cryptography;
using System.IO;
using System.Text;
public string EncryptWithCustomKey(string plainText, byte[] key, byte[] iv)
{
using (RijndaelManaged rijndael = new RijndaelManaged())
{
rijndael.Key = key;
rijndael.IV = iv;
rijndael.Mode = CipherMode.CBC;
rijndael.Padding = PaddingMode.PKCS7;
ICryptoTransform encryptor = rijndael.CreateEncryptor();
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt,
encryptor,
CryptoStreamMode.Write))
{
byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
csEncrypt.Write(plainBytes, 0, plainBytes.Length);
csEncrypt.FlushFinalBlock();
return Convert.ToBase64String(msEncrypt.ToArray());
}
}
}
}
public byte[] GenerateKey()
{
using (RijndaelManaged rijndael = new RijndaelManaged())
{
rijndael.GenerateKey();
return rijndael.Key;
}
}
Cryptography Best Practices
You can use other types of cryptographic encryption and decryption to protect your data. The type of algorithm used depends on the scenario of the application being created. Always use strong keys, never hardcode encryption keys in your source code, and store them securely.
For sensitive data, consider using asymmetric encryption for key exchange and symmetric encryption for the actual data. Always use the most current and secure algorithms available, and be aware that older algorithms like DES are considered weak by modern standards.
FAQ
What's the difference between symmetric and asymmetric cryptography?
Symmetric cryptography uses a single shared key to encrypt and decrypt data, making it faster but requiring secure key exchange. Asymmetric cryptography uses a public/private key pair, where the public key encrypts and the private key decrypts, solving the key distribution problem but being slower.
What is an initialization vector and why is it needed?
An initialization vector (IV) is used when the encryption mode is CipherMode.CBC (Cipher Block Chaining). Since each block is encrypted using the output of the previous block, the IV provides the initial data needed to encrypt the first block, ensuring secure block chaining.
Which encryption algorithm should I choose?
For symmetric encryption, you can use DES, RC2, Rijndael (AES), or TripleDES. Rijndael is generally recommended for new applications as it's the Advanced Encryption Standard. The choice depends on your application scenario, security requirements, and performance needs.
How do I specify my own encryption key instead of using the default?
Set the Key and IV properties of your SymmetricAlgorithm instance before creating the encryptor. Use secure key generation methods and never hardcode keys in your source code. The intended recipient must have the same key to decrypt the data.