0

I've made my own encryption system for in my framework and I've been using it for a while now and it works fine however, I just found a serious issue: if the string that needs to be encrypted is exactly 4 characters long, the second character becomes the last character like so:

1234 > 1434

2408 > 2808

24082408 > 24082408

123 > 123

12 > 12

12345 > 12345

It really only happens when the string is exactly 4 characters, anything less/more and it works absolutely fine!

I have no idea if it's the encryption causing it or the decryption...

The code to encrypt:

 public static string DoEncrypt(string ToEncrypt, [Optional, DefaultParameterValue(true)] bool UseHashing)
    {
        Memory.HasInitializedCheck();
        int intLenght = ToEncrypt.Length - 1;
        string NewString = null;
        for (int intCount = intLenght; intCount >= 0; intCount--)
        {

            if (intCount == 2)
            {
                NewString += ToEncrypt.Substring(intLenght, 1);
            }
            else if (intCount == 1)
            {
                NewString += ToEncrypt.Substring(intLenght - 1, 1);
            }
            else if (intCount == intLenght - 1)
            {
                NewString += ToEncrypt.Substring(1, 1);
            }
            else if (intCount == intLenght)
            {
                NewString += ToEncrypt.Substring(2, 1);
            }
            else
            {
                NewString += ToEncrypt.Substring(intCount, 1);
            }

        }
        char[] array = Application.ProductName.ToCharArray();
        Array.Reverse(array);
        NewString += "#" + new string(array) + "#";


        byte[] keyArray;
        byte[] ToEncryptArray = UTF8Encoding.UTF8.GetBytes(NewString);
        if (UseHashing)
        {
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(MechaKey));
            hashmd5.Clear();
        }
        else
        {
            keyArray = UTF8Encoding.UTF8.GetBytes(MechaKey);
        }
        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        tdes.Key = keyArray;
        tdes.Mode = CipherMode.ECB;
        tdes.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = tdes.CreateEncryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(ToEncryptArray, 0, ToEncryptArray.Length);
        tdes.Clear();
        String FinalEnc = Convert.ToBase64String(resultArray, 0, resultArray.Length);
        return FinalEnc;

    }

And the code to decrypt

 public static string DoDecrypt(string ToDecrypt, [Optional, DefaultParameterValue(true)] bool UseHashing)
    {
        Memory.HasInitializedCheck();
        byte[] keyArray;
        byte[] toEncryptArray = Convert.FromBase64String(ToDecrypt);
        if (UseHashing)
        {
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(MechaKey));
            hashmd5.Clear();
        }
        else
            keyArray = UTF8Encoding.UTF8.GetBytes(MechaKey);

        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        tdes.Key = keyArray;
        tdes.Mode = CipherMode.ECB;
        tdes.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = tdes.CreateDecryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        Array.Reverse(resultArray);
        string UTF = UTF8Encoding.UTF8.GetString(resultArray);
        int lenght = Application.ProductName.Length + 2;
        bool start = false;
        string appname = null;
        try
        {
            if (UTF.Substring(0, lenght) != "#" + Application.ProductName + "#")
            {

                for (int appchecker = 0; appchecker < UTF.Length; appchecker++)
                {
                    if (UTF.Substring(appchecker, 1) == "#" && start == false)
                    {
                        appchecker = appchecker + 1;
                        start = true;
                    }
                    if (start)
                    {
                        appname += UTF.Substring(appchecker, 1);
                    }
                    if (UTF.Substring(appchecker + 1, 1) == "#" && start == true)
                    {
                        break;
                    }
                }

                return "IDMismatch Key belongs to " + appname + " %E01";
            }
        }
        catch
        {

            return "IDMismatch Key lenght incorrect %E02";
        }


        UTF = UTF.Replace("#" + Application.ProductName + "#", "");
        char[] UTFChar = UTF.ToCharArray();
        Array.Reverse(UTFChar);
        int intLengt = UTFChar.Length - 1;
        string NewString = null;
        for (int intCount = 0; intCount <= intLengt; intCount++)
        {

            if (intCount == 2)
            {
                NewString += UTF.Substring(intLengt, 1);
            }
            else if (intCount == 1)
            {
                NewString += UTF.Substring(intLengt - 1, 1);
            }
            else if (intCount == intLengt - 1)
            {
                NewString += UTF.Substring(1, 1);
            }
            else if (intCount == intLengt)
            {
                NewString += UTF.Substring(2, 1);
            }
            else
            {
                NewString += UTF.Substring(intCount, 1);
            }

        }
        tdes.Clear();
        return NewString;
    }


}

I have tried different encryption keys but it didn't change anything.

Can anyone tell me what's wrong?

Thanks

user265889
  • 667
  • 1
  • 10
  • 24
  • 1
    Try skipping the actual encryption so you can check your intermediate values. The problem may be with the 'for' loops. – Doug Domeny Apr 14 '16 at 21:22
  • 1
    See [here](https://stackoverflow.com/questions/202011/encrypt-and-decrypt-a-string) for an answer on encrypting and decrypting a string *without* rolling your own crypto. If you don't want to go through that effort, you'd likely be just as secure just running an XOR filter over any string's bytes. – Alyssa Haroldsen Apr 14 '16 at 21:24
  • @DougDomeny yeah it's definitely the for loop: 12345 > 32541#2noitacilppAsmroFswodniW# 321 > 321#2noitacilppAsmroFswodniW# 1234 > 3431#2noitacilppAsmroFswodniW# – user265889 Apr 14 '16 at 22:04
  • Hopefully you are not using this in production code, perhaps just a class assignment? – zaph Apr 14 '16 at 23:00

1 Answers1

1

The problem lies with the two cases

if (intCount == 1)
{
    NewString += ToEncrypt.Substring(intLenght - 1, 1);
}

and

else if (intCount == intLenght)
{
    NewString += ToEncrypt.Substring(2, 1);
}

With a ToEnrypt of lenght 4, thus intLength = 3, both of these conditions take the third character of ToEncrypt, but none of the others ever can take the second character of the string, as for inputs shorter than 5 characters you can never reach the last else block.

BTW shuffling the input data won't add any significant security to your encryption. Stick to well known encryption schemes and get your security from the size of the key.

derpirscher
  • 14,418
  • 3
  • 18
  • 35