James
James

Reputation: 31738

How to implement Triple DES in C# (complete example)

I want to use triple DES in C# for encryption/decryption of (utf8) strings with a (utf8) key of any length.

I am looking for these three functions

public static string Encrypt(string data, string key)
{
    ...
}

public static string Decrypt(string data, string key)
{
    ...
}

public static string GenerateKeyFromString(string str)
{
    ...
}

Note: Before anyone links to it, the http://www.geekzilla.co.uk/view7B360BD8-A77C-4F1F-BCA0-ACD0F6795F61.htm implementation does not work, I have thoroughly tested it.

I have done lots of searching and found bits of the problem like EncryptOneBlock and others but I am looking for a complete 'for dummies' implementation which I think would be useful for others too.

Thanks in advance!

Upvotes: 20

Views: 102084

Answers (5)

Hiran
Hiran

Reputation: 1180

Anyone who reads this thread 2020 or later, don't use TripleDes because it's not much secure nowadays. You can select AES (advance encryption) instead.

You just need to replace TripleDESCryptoServiceProvider with AesCryptoServiceProvider.

Upvotes: 2

Chris Gessler
Chris Gessler

Reputation: 23113

Complete source here: http://www.codeproject.com/Articles/14150/Encrypt-and-Decrypt-Data-with-C

Encrypt:

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);
}

Decrypt:

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(
                         toDecryptArray, 0, toDecryptArray.Length);
    //Release resources held by TripleDes Encryptor                
    tdes.Clear();
    //return the Clear decrypted TEXT
    return UTF8Encoding.UTF8.GetString(resultArray);
}

Upvotes: 40

Godwin Awojobi
Godwin Awojobi

Reputation: 105

using System;
using System.Configuration;
using System.Security.Cryptography;
using System.Text;

public class TripleDESImp
{
    public static readonly string Key = ConfigurationManager.AppSettings["Encryption_Key"];
    public static readonly Encoding Encoder = Encoding.UTF8;

    public static string TripleDesEncrypt(string plainText)
    {
        var des = CreateDes(Key);
        var ct = des.CreateEncryptor();
        var input = Encoding.UTF8.GetBytes(plainText);
        var output = ct.TransformFinalBlock(input, 0, input.Length);
        return Convert.ToBase64String(output);
    }

    public static string TripleDesDecrypt(string cypherText)
    {
        var des = CreateDes(Key);
        var ct = des.CreateDecryptor();
        var input = Convert.FromBase64String(cypherText);
        var output = ct.TransformFinalBlock(input, 0, input.Length);
        return Encoding.UTF8.GetString(output);
    }

    public static TripleDES CreateDes(string key)
    {
        MD5 md5 = new MD5CryptoServiceProvider();
        TripleDES des = new TripleDESCryptoServiceProvider();
        var desKey= md5.ComputeHash(Encoding.UTF8.GetBytes(key));
        des.Key = desKey;
        des.IV = new byte[des.BlockSize / 8];
        des.Padding=PaddingMode.PKCS7;
        des.Mode=CipherMode.ECB;
        return des;
    }
}

<configuration>
<appsettings>
<add key="Encryption_Key" value="put_your_encryption_key_here"/>
</appsettings>
<configuration>

Upvotes: 7

TheDev6
TheDev6

Reputation: 872

Here is a complete example copy paste ready..

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace MVC3JavaScript_3_2012.Utilities
{
    public class MyTripleDES
    {
 private readonly TripleDESCryptoServiceProvider _des = new TripleDESCryptoServiceProvider();
        private readonly UTF8Encoding _utf8 = new UTF8Encoding();

        /// <summary>
        /// Key to use during encryption and decryption
        /// </summary>
        private byte[] _keyValue;
        public byte[] Key
        {
            get { return _keyValue; }
            private set { _keyValue = value; }
        }

        /// <summary>
        /// Initialization vector to use during encryption and decryption
        /// </summary>
        private byte[] _ivValue;
        public byte[] IV
        {
            get { return _ivValue; }
            private set { _ivValue = value; }
        }

        /// <summary>
        /// Constructor, allows the key and initialization vector to be provided as strings
        /// </summary>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        public MyTripleDES(string key, string iv)
        {
            _keyValue = Convert.FromBase64String(key);
            _ivValue = Convert.FromBase64String(iv);
        }

        /// <summary>
        /// Decrypt Bytes
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public byte[] Decrypt(byte[] bytes)
        {
            return Transform(bytes, _des.CreateDecryptor(_keyValue, _ivValue));
        }

        /// <summary>
        /// Encrypt Bytes
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public byte[] Encrypt(byte[] bytes)
        {
            return Transform(bytes, _des.CreateEncryptor(_keyValue, _ivValue));
        }

        /// <summary>
        /// Decrypt a string
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public string Decrypt(string text)
        {
            byte[] input = HttpServerUtility.UrlTokenDecode(text);
            byte[] output = Transform(input, _des.CreateDecryptor(_keyValue, _ivValue));
            return _utf8.GetString(output);
        }

        /// <summary>
        /// Encrypt a string and return Base64String
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public string Encrypt(string text)
        {
            byte[] input = _utf8.GetBytes(text);
            byte[] output = Transform(input, _des.CreateEncryptor(_keyValue, _ivValue));
            return HttpServerUtility.UrlTokenEncode(output);
        }

        /// <summary>
        /// Encrypt or Decrypt bytes.
        /// </summary>
        private byte[] Transform(byte[] input, ICryptoTransform cryptoTransform)
        {
            // Create the necessary streams
            using (var memory = new MemoryStream())
            {
                using (var stream = new CryptoStream(memory, cryptoTransform, CryptoStreamMode.Write))
                {
                    // Transform the bytes as requested
                    stream.Write(input, 0, input.Length);
                    stream.FlushFinalBlock();

                    // Read the memory stream and convert it back into byte array
                    memory.Position = 0;
                    var result = new byte[memory.Length];
                    memory.Read(result, 0, result.Length);

                    // Return result
                    return result;
                }
            }
        }

        public static string CreateNewVector()
        {
            using (var des = new System.Security.Cryptography.TripleDESCryptoServiceProvider())
            {
                des.GenerateIV();
                return Convert.ToBase64String(des.IV);
            }
        }

        public static string CreateNewKey()
        {
            using (var des = new System.Security.Cryptography.TripleDESCryptoServiceProvider())
            {
                des.GenerateKey();
                return Convert.ToBase64String(des.Key);
            }
        }
    }
}

Upvotes: 2

DayTimeCoder
DayTimeCoder

Reputation: 4332

Why not use the .Net Cryptography Library ,it has DES and Triple DES implementations. I would suggest not to reinvent the wheel and use the library ,Well if you need to practice and sharpen your skills than its great to roll out your own implementation ! :)

private static void EncryptData(String inName, String outName, byte[] tdesKey, byte[] tdesIV)
{    
//Create the file streams to handle the input and output files.
FileStream fin = new FileStream(inName, FileMode.Open, FileAccess.Read);
FileStream fout = new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);
fout.SetLength(0);

//Create variables to help with read and write.
byte[] bin = new byte[100]; //This is intermediate storage for the encryption.
long rdlen = 0;              //This is the total number of bytes written.
long totlen = fin.Length;    //This is the total length of the input file.
int len;                     //This is the number of bytes to be written at a time.

TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();          
CryptoStream encStream = new CryptoStream(fout, tdes.CreateEncryptor(tdesKey, tdesIV), CryptoStreamMode.Write);

Console.WriteLine("Encrypting...");

//Read from the input file, then encrypt and write to the output file.
while(rdlen < totlen)
{
    len = fin.Read(bin, 0, 100);
    encStream.Write(bin, 0, len);
    rdlen = rdlen + len;
    Console.WriteLine("{0} bytes processed", rdlen);
}

encStream.Close();                     
}


Source: MSDN

Upvotes: 5

Related Questions