Question

I am trying to do an exercise which includes to decrypt a given encrypted session key with a given shared key. I have decrypted the session key and printed the byte array on screen. (Same result is printed when ever I run the program).

Then to check my work I am trying to encrypt the decrypted session key again (obviously with the same shared key) but the result is different all the time it, when is supposed to give me back the original encrypted session key.

I cannot understand were is my mistake....

Thanks

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

namespace Crypto
{
    public class Program
    {
        static void Main(string[] args)
        {

        //Shared Master Key
        byte[] mkByteArray = { 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23 };

        //Encrypted Session Key
        byte[] eskByteArray = { 0x4a, 0x4d, 0xe6, 0x87, 0x82, 0x47, 0xd3, 0x7b };

        PrintByteArray(eskByteArray);

        DES des = new DESCryptoServiceProvider();
        des.Mode = CipherMode.ECB;
        des.Padding = PaddingMode.None;
        des.Key = mkByteArray;

        ICryptoTransform ct1 = des.CreateDecryptor();
        byte[] resultArray1 = ct1.TransformFinalBlock(eskByteArray, 0, eskByteArray.Length);
        des.Clear();
        PrintByteArray(resultArray1);

        ICryptoTransform ct2 = des.CreateEncryptor();
        byte[] resultArray2 = ct2.TransformFinalBlock(resultArray1, 0, resultArray1.Length);
        des.Clear();
        PrintByteArray(resultArray2);
        }

        //-----Method to print the byte array on screen-----
        public static void PrintByteArray(byte[] bytes)
        {
            var sb = new StringBuilder("new byte[] { ");
            foreach (var b in bytes)
            {
                sb.Append(b + ", ");
            }
            sb.Append("}");
            Console.WriteLine(sb.ToString());
        }

    }
}
Was it helpful?

Solution

I found your problem, but now I am checking why it occurs exactly.

You call des.Clear(); between encrypting and decrypting, if you do not do this, the input and output is the same.


From Msdn:

When called, the Clear method overwrites all sensitive data within the object with zeros

Thus your masterkey in your DES object is set to zero which is why your output is different.

OTHER TIPS

This happens because of the Initialisation Vector. This behaviour is there by design. You don't want the encryption algorithm to produce exactly the same output for the same input. Such algorythm is susceptible to plain text attack, where attacker can potentially infer encryption key from the input and the produced output.

This happens in the line

ICryptoTransform ct2 = des.CreateEncryptor();

According to msdn

If the current IV property is null, the GenerateIV method is called to create a new random IV.

To fix this you need to set the IV for your encryptor. You would then store IV alongside the encrypted bytes and use it for decryption. IV, in simple words, is some initial random noise that allows encryption algorithm to produce different input. As a good practise, this noise must be different for each encryption call.

Obviously, DES is a really weak algorithm, you would want to use at least 3DES. But even 3DES is only used for legacy applications. Modern applications use AES.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top