简体   繁体   English

C#奇怪的加密问题

[英]C# Weird encryption issue

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: 我已经在自己的框架中创建了自己的加密系统,并且已经使用了一段时间,但是它可以正常工作,但是我发现一个严重的问题:如果需要加密的字符串正好是4个字符长,第二个字符变为最后一个字符,如下所示:

1234 > 1434 1234> 1434

2408 > 2808 2408> 2808

24082408 > 24082408 24082408> 24082408

123 > 123 123> 123

12 > 12 12> 12

12345 > 12345 12345> 12345

It really only happens when the string is exactly 4 characters, anything less/more and it works absolutely fine! 实际上,只有在字符串恰好为4个字符(少/多)时,它才会发生,并且绝对可以正常工作!

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 谢谢

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. 如果ToEnrypt的长度为4,则intLength = 3 ,这两个条件都采用ToEncrypt的第三个字符,但是其他任何一个都不能采用字符串的第二个字符,因为对于少于5个字符的输入,您将永远无法达到最后else块。

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. 坚持使用众所周知的加密方案,并从密钥的大小上获得安全性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM