Tek Eye Logo

Tek Eye

Encrypt Decrypt of a String in C# .NET

Cryptography is a big subject area and extremely important for modern software and programs. If you are writing any type of software you need an understanding of software security and methods to keep data, code and users secure. Encrypting data keeps it secure because it hides its meaning, converting the plaintext (or cleartext) to ciphertext. To see the data again you need to decrypt the ciphertext back to plaintext. A simple example is the encryption of passwords to protect them from use by others.

Encryption

C# Encryption and Decryption of a String With a Simple Function

Encryption and decryption of a password or other strings containing data can be done in many ways. There are many character substitution or transposition methods that pre-date the computing era and can be traced back to classical times. Modern computer based methods use symmetric key and asymmetric key mathematical algorithms. There are lots of well established algorithms from which to choose. However not everyone wants to take a course in cryptography just to be able to encrypt a string to hide some data and decrypt it back again. That’s where this example C# encryption and decryption code comes in handy. This code was tested in Visual Studio 2013. (Update: Tested OK in Visual Studio 2017)

C# String Encryption

String Encryption and Decryption for Basic Low Level Confidentiality

The following C# code has been boiled down to an encryption function that takes a plaintext string and passphrase and returns an encrypted string. There is the reverse function that takes the ciphertext and the passphrase and returns the plaintext. This is a quick and easy method of adding some encryption to a C# project, or any .NET project. The encrypt decrypt C# string functions are in a simple class. An example project shows how simple it is to use them. Thus:

Encryption of a string in C# with a password is as simple as:

textBoxEncrypted.Text = Encrypt.EncryptString(textBoxString.Text, textBoxPassword.Text);

Decryption is just as easy:

textBoxString.Text = Encrypt.DecryptString(textBoxEncrypted.Text, textBoxPassword.Text);

Overview of the Encryption and Decryption Functions

The code presented here is not going to be explained in detail. Instead it is recommended that it is studied. The reader should to refer to online resources and the Microsoft .NET Framework documentation on the System.Security.Cryptography namespace. The code was picked up from the Stack Overflow question Encrypting and Decrypting a String in C#. The encrypt and decrypt demo source code in this article should be easy enough to use in your project.

This code is using a symmetric key algorithm known as Rijndael (after the inventors Vincent Rijmen and Joan Daemen), which is implemented by the .NET Framework. This algorithm performs substitutions and permutations on data blocks with keys sized in multiples of 32 bits. The cipher mode is Cipher Block Chaining (CBC) which can take a different Initialisation Vector (IV) for each use to further obfuscate the cipher text. In which case the same passphrase and plaintext will produce different ciphertexts if a different IV is used. Important: Change the IV string for you own value or generate a random one (this can be done at https://www.random.org/strings/). The passphrase is not salted but can be, see the documentation for PasswordDeriveBytes. Note that the encryption and decryption is performed on bytes and not Unicode characters hence the conversion from strings to byte arrays in the code (it also means that these functions can be adapted for other data types if required).

The Free to Use Encryption and Decryption C# Code

//Don't forget the using System.Security.Cryptography; statement when you add this class
public static class Encrypt
{
    // This size of the IV (in bytes) must = (keysize / 8).  Default keysize is 256, so the IV must be
    // 32 bytes long.  Using a 16 character string here gives us 32 bytes when converted to a byte array.
    private const string initVector = "pemgail9uzpgzl88";
    // This constant is used to determine the keysize of the encryption algorithm
    private const int keysize = 256;
    //Encrypt
    public static string EncryptString(string plainText, string passPhrase)
    {
        byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
        byte[] keyBytes = password.GetBytes(keysize / 8);
        RijndaelManaged symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
        cryptoStream.FlushFinalBlock();
        byte[] cipherTextBytes = memoryStream.ToArray();
        memoryStream.Close();
        cryptoStream.Close();
        return Convert.ToBase64String(cipherTextBytes);
    }
    //Decrypt
    public static string DecryptString(string cipherText, string passPhrase)
    {
        byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
        byte[] keyBytes = password.GetBytes(keysize / 8);
        RijndaelManaged symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;
        ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
        MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
        CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
        byte[] plainTextBytes = new byte[cipherTextBytes.Length];
        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
        memoryStream.Close();
        cryptoStream.Close();
        return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
    }
}

The small example project (see the image at the top of the article) shows the encrypt decrypt functionality in action. Create a similar WinForm or download the code, which has the dialog.

See Also

Archived Comments

Sam on June 28, 2015 at 8:11 am said:

Thanks for this code it looks like what I was in need of for a simple application with a little bit of sensitive data.

Sam on June 28, 2015 at 8:20 am said:

System.IO is also required in the name space for the memory stream.


Kochav on August 24, 2015 at 1:52 pm said:

Thanks for this code it is exactly what I was in need of for encrypt a string in a batch file.


Kyle on December 7, 2015 at 5:14 am said:

I tried this, encryption works but when I go to decrypt, I get an error when it tries to figure out the decrypted byte count.

Any ideas?

Tek Eye on December 7, 2015 at 9:18 am said:

Does the example project work OK for you?


ZVey on January 28, 2016 at 10:39 am said:

This example is perfect for my usecase but there is only one problem. I want to use encrypted key inside URL so when I get that encrypted key I decrypted it and get the id of the product and bind the product. But I realized that ecrypted key contains "/" which is not good for URLs. Is there any way to fix that?

Thanks in advance.

ZVey on January 28, 2016 at 10:46 am said:

BTE "+" is not good for urls too. So basicly I want to use same logic with a proper encrypted string for URLs.

ZVey on January 28, 2016 at 11:22 am said:

Anyways. found a way.at the end of EncryptString method instead of returning "return Convert.ToBase64String(cipherTextBytes)" write the code below .

var encodedURL= HttpUtility.UrlEncode(Convert.ToBase64String(cipherTextBytes));
return encodedURL;

Tek Eye on January 28, 2016 at 8:38 pm said:

Perfect. Very useful.


Lino on April 22, 2016 at 11:07 am said:

Hello, excuse my ignorance.

Why at the end of encryption password, or whatever the string I appear \ == \ ?

Thank you!

Tek Eye on April 22, 2016 at 11:19 am said:

The encrypted text consists of printable characters, = is a printable character, it is chance that two = characters appeared at the end. Due to the nature of the mathematics used the encrypted output (ciphertext) appears as a random string of characters and == happened to occur.


Joe on August 13, 2016 at 6:38 pm said:

Awesome, thanks for sharing!


awesomeWoz on November 28, 2016 at 11:23 am said:

Very nice tutorial! Encryption was good. Unfortunately there was an error on decryption.

"Padding is invalid and cannot be removed."

Tek Eye on November 28, 2016 at 1:43 pm said:

That error message is usually as a result of an implementation problem. Plenty of examples on Stack Overflow:

https://stackoverflow.com/search?q=Padding+is+invalid+and+cannot+be+removed

Have you run the provided example project?


carter on January 7, 2017 at 3:41 pm said:

How to make it can encrypt or decrypt more than one ? bulk encrypt/decryt? Thank you.

Tek Eye on January 8, 2017 at 11:09 am said:

You need to be a bit more specific with your requirements. For multiple strings (e.g. stored in an array) use a loop calling the routine for each string in turn.

carter on January 8, 2017 at 9:37 pm said:

Can you give example? Thank you.

Tek Eye on January 8, 2017 at 10:49 pm said:

string[] toEncrypt = { "string one", "string two", "string three" };
string[] encrypted = { "", "", "" };
int i = 0;

foreach(string s in toEncrypt)
{
    encrypted[i] = Encrypt.EncryptString(s, "Password");
    ++i;
}

cipher007 on February 22, 2017 at 6:11 am said:

Your decrypt uses ASCII when getting the initVectorByte[], your encrypt uses UTF8

Tek Eye on March 3, 2017 at 4:53 pm said:

Thanks, good spot, updated.


Angelica Gomez on March 27, 2017 at 11:03 pm said:

Hello! Please confirm if the sample code above can be freely used by any developer – no license/copyright needed. Thank you.

Tek Eye on March 28, 2017 at 7:01 am said:

Yes, free to use, no restrictions, public domain. However, this also means there is no warranty and the user needs to take full responsibility for using the code.

Author:  Published:  Updated:  

ShareSubmit to TwitterSubmit to FacebookSubmit to Google+Submit to LinkedInSubmit to redditPrint Page

markdown CMS Small Logo Icon ↓markdown↓ CMS is fast and simple. Build websites quickly and publish easily. For beginner to expert.



Articles on:

Android, HTML, VPS, Computing, IT, Computer History, ↓markdown↓ CMS



Free Android Projects and Samples:

Android Examples, Android List Examples, Android UI Examples