Криптография C# .NET не расшифровывается должным образом

Я пытаюсь зашифровать и расшифровать текст в C# (.NET 3.5), выясняя, что этот простой код не работает:

    private const string KEY = "Chiave";

    static void Main(string[] args)
    {

        string plainText = "Data to be encrypted";

        byte[] keyArray;
        MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
        keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(KEY));

        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(plainText);

        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
        tdes.Key = keyArray;
        tdes.Mode = CipherMode.CBC;
        tdes.Padding = PaddingMode.PKCS7;

        ICryptoTransform cTransform = tdes.CreateEncryptor();
        byte[] encArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

        tdes = new TripleDESCryptoServiceProvider();
        tdes.Key = keyArray;
        tdes.Mode = CipherMode.CBC;
        tdes.Padding = PaddingMode.PKCS7;

        cTransform = tdes.CreateDecryptor();
        byte[] decArray = cTransform.TransformFinalBlock(encArray, 0, encArray.Length);

        if (encArray.Length == decArray.Length)
        {
            for (int i = 0; i < encArray.Length; ++i)
                Console.Out.Write("{0,3}|{1,3}", encArray[i], decArray[i]);
        } else
            Console.Out.Write("Length error!");

        Console.In.Read();
    }

Кажется, что фаза шифрования или дешифрования портит некоторые байты в начале текста (иным образом, каждый раз, когда я запускаю программу), иногда изменяя даже длину байтового массива. Я смог заставить его работать, используя ECB-шифр, но мои данные имеют некоторые статические блоки, которые в любое время приводят к одному и тому же результату.

С https://msdn.microsoft.com/it-it/library/system.security.cryptography.ciphermode(v=vs.110).aspx о ECB:

Важный: этот режим не рекомендуется, потому что он открывает дверь для нескольких эксплойтов безопасности. Если зашифрованный текст содержит многократные повторения, возможно, что зашифрованный текст может быть разбит по одному блоку за раз. Также можно использовать анализ блоков для определения ключа шифрования. Кроме того, активный злоумышленник может заменять и обменивать отдельные блоки без обнаружения, что позволяет сохранять блоки и вставлять их в поток в других точках без обнаружения.

Вот некоторые результаты после энк. и дек.:

��u��T�be encrypted
U����ŋbe encrypted
5�AL\"0be encrypted

И так далее, спасибо за совет.

1 ответ

Решение

Вы создали новый экземпляр TripleDESCryptoServiceProvider но этот новый экземпляр имеет не то же значение IV первого

Кроме того, некорректно сравнивать длину зашифрованного массива с длиной дешифрованного. Вы должны попытаться вернуть исходную строку и проверить, равны ли два

private const string KEY = "Chiave";
static void Main(string[] args)
{
    string plainText = "Data to be encrypted";

    byte[] keyArray;
    MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
    keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(KEY));

    byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(plainText);

    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    tdes.Key = keyArray;
    tdes.Mode = CipherMode.CBC;
    tdes.Padding = PaddingMode.PKCS7;

    ICryptoTransform cTransform = tdes.CreateEncryptor();
    byte[] encArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

    // REMOVE THESE LINES 
    // tdes = new TripleDESCryptoServiceProvider();
    // tdes.Key = keyArray;
    // tdes.Mode = CipherMode.CBC;
    // tdes.Padding = PaddingMode.PKCS7;

    cTransform = tdes.CreateDecryptor();
    byte[] decArray = cTransform.TransformFinalBlock(encArray, 0, encArray.Length);

    // if (encArray.Length == decArray.Length)
    // {
    //    for (int i = 0; i < encArray.Length; ++i)
    //        Console.Out.Write("{0,3}|{1,3}", encArray[i], decArray[i]);
    //} else
    //    Console.Out.Write("Length error!");

    string result = UTF8Encoding.UTF8.GetString(decArray);
    Console.WriteLine(result);

    Console.In.Read();
}
Другие вопросы по тегам