Click here to Skip to main content
Click here to Skip to main content

Encrypt and Decrypt Data with C#

By , 17 May 2006
 

Introduction

Well, most beginner and intermediate programmers like to play with cryptography. This is the part that took me to some trouble in my life. A good encryption and decryption code is easily found on the Internet and even on The Code Project. Why another? I did not find a suitable reason behind that. And when I found some, I mixed them up and this is the result. I wanted to share the result and hence this article.

The Solution

solution Image - solution.jpg

I included a tiny demo solution with an implementation of the segment. Hope it helps you. As you see from the snapshot, the CryptorEngine class holds the two static methods encryption and decryption. The reason I put them into a separate file is because it is the best practice as far as I know and most importantly, other blocks can access these methods easily.

The Encryption

encrypt Image - encrypt.jpg

The encrypt method goes like this. I need to say something about the cipherMode of the tripleDES cryptographic service provider. We used the ECB(Electronic Code Book). The ECB mode encrypts each block individually. This means that any blocks of plain text that are identical and are in the same message or even in a different message but encrypted with the same key will be transformed into identical cipher text blocks. If the plain text to be encrypted contains substantial repetition, it is feasible for the cipher text to be broken one block at a time. Also it is possible for an active adversary to substitute and exchange individual blocks without detection. If a single bit of the cipher text block is mangled, the entire corresponding plain text block will be mangled.

    public static string Encrypt(string toEncrypt, bool useHashing)
    {
        byte[] keyArray;
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

        System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
        // Get the key from config file

        string key = (string)settingsReader.GetValue("SecurityKey", typeof(String));
        //System.Windows.Forms.MessageBox.Show(key);
        //If hashing use get hashcode regards to your key
        if (useHashing)
        {
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            //Always release the resources and flush data
            //of the Cryptographic service provide. Best Practice

            hashmd5.Clear();
        }
        else
            keyArray = UTF8Encoding.UTF8.GetBytes(key);

        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        //set the secret key for the tripleDES algorithm
        tdes.Key = keyArray;
        //mode of operation. there are other 4 modes. We choose ECB(Electronic code Book)
        tdes.Mode = CipherMode.ECB;
        //padding mode(if any extra byte added)
        tdes.Padding = PaddingMode.PKCS7;

        ICryptoTransform cTransform = tdes.CreateEncryptor();
        //transform the specified region of bytes array to resultArray
        byte[] resultArray = cTransform.TransformFinalBlock
                (toEncryptArray, 0, toEncryptArray.Length);
        //Release resources held by TripleDes Encryptor
        tdes.Clear();
        //Return the encrypted data into unreadable string format
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

Decryption

decrypt Image - decrypt.jpg

Well, as you can see, the decryption method is kind of opposite of the encryption. I talked about the Cipher Mode ECB in the encrypt section. Now let's talk about the padding mode PKCS7. Padding comes when a message data block is shorter than the full number of bytes needed for a cryptographic operation. Why did we choose PCKS7. Because PCKS#7 padding string consists of a sequence of bytes, each of which is equal to the total number of padding bytes added.

    public static string Decrypt(string cipherString, bool useHashing)
    {
        byte[] keyArray;
        //get the byte code of the string

        byte[] toEncryptArray = Convert.FromBase64String(cipherString);

        System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
        //Get your key from config file to open the lock!
        string key = (string)settingsReader.GetValue("SecurityKey", typeof(String));

        if (useHashing)
        {
            //if hashing was used get the hash code with regards to your key
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            //release any resource held by the MD5CryptoServiceProvider

            hashmd5.Clear();
        }
        else
        {
            //if hashing was not implemented get the byte code of the key
            keyArray = UTF8Encoding.UTF8.GetBytes(key);
         }

        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        //set the secret key for the tripleDES algorithm
        tdes.Key = keyArray;
        //mode of operation. there are other 4 modes.
        //We choose ECB(Electronic code Book)

        tdes.Mode = CipherMode.ECB;
        //padding mode(if any extra byte added)
        tdes.Padding = PaddingMode.PKCS7;

        ICryptoTransform cTransform = tdes.CreateDecryptor();
        byte[] resultArray = cTransform.TransformFinalBlock
                (toEncryptArray, 0, toEncryptArray.Length);
        //Release resources held by TripleDes Encryptor
        tdes.Clear();
        //return the Clear decrypted TEXT
        return UTF8Encoding.UTF8.GetString(resultArray);
    }

Web.Config/App.Config file. Why?

Well, you want to change your key. But you are not the developer or you do not even have the source?! Then what. Thanks to Web.config/app.config file idea. Keep your secret key in the config file. Change it when you need it.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  // The Code Project does not recognize these tags if i put<>.
  // So you Put   <> beside the words
  appSettings>

How to Use

To use the code sample, you can copy the CryptorEngine to your project and start playing or copy the method bodies and paste them to your application projects.

To Do

You can try to encrypt the key and save it (encrypted) to the config file for an extra bit of security.

Conclusion

This code works fine with .NET 1.1. I built the project in Visual Studio 2005 because some methods expired in .NET 2.0 and changed. For example, the configuration namespace is changed a lot. So I built the example in Visual Studio 2005 to see if it works on v2.0 too. And it works with ZERO change and ZERO error.

History

  • 18th May, 2006: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Syed Moshiur Murshed
Software Developer Poolarserver Schwägerl & Friedle Gbr
Bangladesh Bangladesh
Member
I am Syed Moshiur Murshed from Bangladesh. I studied BSC in Computer Science at American International University Bangladesh(www.aiub.edu). And now I am studing MSC in Software Technology at Stuttgart University of Applied Science, Germany(www.hft-stuttgart.de). Meanwhile I also have been working as a student programmer on poolarserver Schwägerl & Friedle Gbr(www.poolarserver.com), a stuttgart based Software Company since 01.08.2009. I have been learning C# for quite some time and Enjoying it.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionDecrypting the same for duplicate passwordsmemberDorababu74321 Jan '13 - 2:04 
Hi syed if I enter my password as Dorababu for one user and also the same password for other user the decryption is same for both the passwords, how can I decrypt to different one
Dorababu
http://dorababu-meka.blogspot.in/

AnswerRe: Decrypting the same for duplicate passwordsmemberAron Weiler25 Feb '13 - 19:55 
Use a salt value (random set of bytes) in conjunction with the unencrypted value when encrypting... The output will appear random.
 
Be sure to store the salt value with the encrypted sting if you're doing password management.
GeneralMy vote of 5membermanoj kumar choubey29 Mar '12 - 23:28 
Nice
GeneralThis code is not securemembermatthev19 May '09 - 21:41 
Please see: http://www.codinghorror.com/blog/archives/001267.html[^]
 
Don't use it unless you understand implications, especially with this line:
tdes.Mode = CipherMode.ECB;

GeneralRe: This code is not securememberDorababu74321 Jan '13 - 2:02 
Hi if we remove that will it encrypt the password
Dorababu
http://dorababu-meka.blogspot.in/

GeneralRe: This code is not securememberAron Weiler25 Feb '13 - 19:56 
I second this... ECB is broken.
Questionwhat magnificentmembersnopbear1 Feb '09 - 1:51 
magnificent code i have try it with web appliction and it works fine thanksRose | [Rose] Shucks | :->
GeneralError : Invalid length for a Base-64 char arraymembercontact_niraj28 May '08 - 2:08 
I m getting this error while decrypting. Can u plz help on this.
 
Invalid length for a Base-64 char array
byte[] toEncryptArray = Convert.FromBase64String(cipherString);
 

 
Thanks,
 
Niraj
GeneralRe: Error : Invalid length for a Base-64 char arraymembergeardoom314 Nov '08 - 5:29 
Same problem. No clues
 
I tried using any kind of key length like 24 caracters long and same problem. Is there any fix for that ?
 
geardoom3gmail.com
GeneralRe: Error : Invalid length for a Base-64 char arraymemberMember 336081819 Dec '08 - 0:41 
The Encryption sometimes leave "+" symbols, which some methods replace with a space " "
Any spaces will cause this error when there is a space in the string when you call Convert.FromBase64String()
 
Haven't found a sure solution
GeneralGreat example....memberKebrite8 Feb '08 - 17:57 
Thanks mate for the very clear example you've presented! It is EXACTLY what I was looking for !!!!
GeneralExcellent articlememberNishant Rana (Nishu)28 Nov '07 - 2:36 
Thanks Moshiur for posting such an excellent article. It was very useful.
 
Nishant Rana

NewsTwo other related encryption articles in CodeProject ...memberTony Selke27 Sep '07 - 6:53 
You may also be interested in looking at the following, related Code Project articles:
 
Generic SymmetricAlgorithm Helper[^]
This is a generic helper class that exposes simplified Encrypt and Decrypt functionality for strings, byte arrays and streams for any SymmetricAlgorithm derivative (DES, RC2, Rijndael, TripleDES, etc.).
 
Making TripleDES Simple in VB.NET and C#[^]
This is a simple wrapper class that provides an easy interface for encrypting and decrypting byte arrays and strings using the 3DES algorithm.

QuestionCan you give the old version of framework 1.1,thank you!memberqushui11 Mar '07 - 21:52 
I am a programer of China,I work need that function,if you have free time,please send to me oksummer@163.com,thank you a lot.
AnswerRe: Can you give the old version of framework 1.1,thank you!memberJoel Hess13 Jun '07 - 13:54 
Not sure if you got a response, but the author says in the posting that the code works in .Net 1.1 and 2.0
Generalkey lengthmemberCris C.2 Mar '07 - 2:50 
Just thought I would mention this as new developers may run into the same problem I had. I copied this code and tried it and couldnt get it to work. I kept getting the error below.
 
Specified key is not a valid size for this algorithm
 
After trying different keys without success, I learned that the length of the key matters. TripleDES encryption requires a key that is 24 characters in length. If you want to switch to simple DES encryption, the key must be 8 chars in length. If you use a key with a different length, you will get the exception mentioned earlier.
 
Good luck and thanks to Syed for the example.
 
--Cris

GeneralRe: key lengthmemberJoel Hess13 Jun '07 - 13:55 
Thanks for the tip. I did the exact thing that you did and just copied the code (and subsequently got the same exception).
 

GeneralRe: key lengthmembervurso7861 Jul '07 - 8:32 
I found that as well but I got around it by adding a new function that checks the key length.
 
Psuedo code:
 
if keyArray > 24 then
trim(keyArray) to 24 characters
else if keyarray < 24 then
padding(keyArray) to 24 characters
 
That works like a charm, if your padding the keyArray then you will need an additional function to generate some random characters. I just used a simple function that picks some random characters out of an array and injects them into the keyArray until its the right size.
 

GeneralRe: key lengthmembersachinmulange13 Aug '07 - 2:38 
please could u explain in detail ..?
 
Thanks,
Sachin
GeneralThe other way aroundmemberdaviddastar14 Dec '06 - 19:25 
What about the other way around?
 
Do you have a program that decrypt the PKCS#7 code into readable words?
 
Thanks for your answer
Generalerror : system.FormatExceptionmemberzhao53430 May '06 - 23:54 
Base-64 character string be of no effect
 
in ( byte[] toEncryptArray = Convert.FromBase64String(cipherString); )
 
i don't why?
 
please give a feedback~
GeneralRe: error : system.FormatExceptionmemberzhao53431 May '06 - 22:16 
Roll eyes | :rolleyes: hehe Poke tongue | ;-P
i get it.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 18 May 2006
Article Copyright 2006 by Syed Moshiur Murshed
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid