Проблема с расшифровкой AES/ECB с использованием PCKS5 в C#


Мне нужно расшифровать изображение, поступающее из онлайн-сервиса (это не мой сервис, поэтому я должен использовать этот способ шифрования).
Это изображение зашифровано с помощью AES/ECB с одним синхронным ключом и дополнено с помощью PKCS5.

Я пробовал несколько способов добиться этого, но ни один из них не работал. Я использую криптографическую библиотеку BoucyCastle.

Вот мой код расшифровки:

    public static byte[] Decrypt(string input)
    {
        var cipher = CipherUtilities.GetCipher("AES/ECB/PKCS5Padding");
        cipher.Init(false, new KeyParameter(Encoding.UTF8.GetBytes(KEY)));
        byte[] todo = Encoding.UTF8.GetBytes(Pad(input));
        byte[] bytes = cipher.ProcessBytes(todo);
        byte[] final = cipher.DoFinal();

        // Write the decrypt bytes & final to memory...
        var decryptedStream = new MemoryStream(bytes.Length);
        decryptedStream.Write(bytes, 0, bytes.Length);
        decryptedStream.Write(final, 0, final.Length);
        decryptedStream.Flush();

        var decryptedData = new byte[decryptedStream.Length];
        decryptedStream.Read(decryptedData, 0, (int)decryptedStream.Length);
        return decryptedData;
    }

    private static string Pad(string data)
    {
        int len = data.Length;
        int toAdd = (16 - len % 16);
        for (int i = 0; i < toAdd; i++)
        {
            data += (char)toAdd;
        }
        return data;
    }

Когда я пытаюсь это сделать, возникает выражение InvalidCipherTextExpression с сообщением "Повреждён блок заполнения" в строке byte[] final = cipher.DoFinal();.
Я протестировал свою функцию заполнения, и она, похоже, работает должным образом.
Я попытался заглянуть внутрь исходного кода BouncyCastle. чтобы найти мою ошибку, и я обнаружил, что в последнем блоке нет заполнения, и это вызывает ошибку. Поэтому мне интересно, не делаю ли я что-то не так где-то еще, потому что это может быть не из заполнения.
Возможно, входная строка, которая извлекается с http-сервера с помощью этого:

        // grab te response and print it out to the console along with the status code
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        return new StreamReader(response.GetResponseStream()).ReadToEnd();

Я хочу добиться того же, что и здесь: C# Расшифровка AES /ECB дополнен с использованием PKCS#5
Но авансеров нет, так как спрашивающий ничего не пробовал..

Заранее спасибо, и мне очень жаль мой плохой английский.


person Rom11    schedule 13.01.2014    source источник
comment
с одним синхронным ключом Что такое синхронный ключ?   -  person Duncan Jones    schedule 13.01.2014
comment
Я действительно не знаю, это то, что я нашел в документации.   -  person Rom11    schedule 13.01.2014
comment
В ПОРЯДКЕ. Из интереса, вы можете дать ссылку на документацию?   -  person Duncan Jones    schedule 13.01.2014
comment
gibsonsec.org/snapchat/fulldisclosure/#encrypting-normal-snaps нашел это здесь. (Я не знаю, имею ли я право публиковать это здесь, так как это не официальная документация..)   -  person Rom11    schedule 13.01.2014
comment
Почему вы заполняете перед расшифровкой? Порядок операций должен быть следующим: заполнение -> шифрование -> передача -> дешифрование -> расшифровка.   -  person wallenborn    schedule 13.01.2014
comment
@wallenborn Верно. На самом деле, вам вообще не нужно беспокоиться о распаковке — библиотека BouncyCastle сделает это за вас.   -  person Duncan Jones    schedule 13.01.2014
comment
Я дополняю перед расшифровкой, так как видел это в другой реализации на Python, и это работает хорошо. Когда я пытаюсь расшифровать без заполнения, я получаю другую ошибку: последний блок неполный в расшифровке   -  person Rom11    schedule 13.01.2014


Ответы (1)


У вас неполный зашифрованный текст — данные, зашифрованные с помощью AES-128, всегда будут кратны 128/8 = 16 байтам. т.е. Last block incomplete in decryption означает, что у вас есть, скажем, 127 байт зашифрованного текста вместо 128.

Как сказано в комментариях, вы не должны дополнять зашифрованный текст перед расшифровкой. «Это сработало», потому что ваша функция на самом деле ничего не добавляла — по причине, указанной выше.

Вы уверены, что используете те же «разрядные» разновидности AES? (например, может случиться так, что вы расшифруете зашифрованный текст AES-128 с помощью AES-192)

P.S. Кстати, cipher.Init(false, new KeyParameter(Encoding.UTF8.GetBytes(KEY))); тоже выглядит подозрительно. Вы уверены, что это не Base64 или что-то подобное?

person DarkWanderer    schedule 13.01.2014
comment
Именно это и было, спасибо! Проблема возникла из-за того, что я получаю байты из строки и, кстати, теряю некоторые. Теперь я получаю байты непосредственно из потока ответов HTTP! - person Rom11; 13.01.2014