Расшифровка небольшого количества байтов с использованием AES - PullRequest
2 голосов
/ 09 февраля 2012

Я пытаюсь расшифровать некоторые данные, которые я получаю через сокет TCP.Это делается с использованием класса RijndaelManaged в режиме CFB.Моя проблема в том, что я не уверен, как я должен расшифровать данные, так как я имею дело только с несколькими байтами (от 8 до 20 в зависимости от сообщения).Когда я вызываю TransformFinalBlock с 10-байтовым byte[], я получаю исключение с сообщением: «Длина данных для расшифровки недопустима».Если я вызываю TransformBlock с этими 10 байтами, я получаю: «Значение недопустимо».Итак, вот мои вопросы:

  1. Сообщение, которое я получаю, имеет длину остальной части сообщения в первых 4 байтах.Как я могу расшифровать только эти байты, чтобы определить длину для продолжения чтения?
  2. Даже если я временно жестко закодирую количество байтов для чтения до 10 (для этого конкретного сообщения) и прочитаю их из сети, как можноЯ расшифровываю эти 10 байтов?

Я также пытался использовать CryptoStream, чтобы он считывался прямо из моего NetworkStream.Тем не менее, любые вызовы чтения на нем, кажется, блокировать на неопределенный срок.У меня такое чувство, что он ожидает, что будет отправлено больше данных (возможно, это будет полный размер блока в байтах).

У меня нет доступа к другому узлу, который отправляет эти данные в сеть, поэтому я могуНе меняйте протокол, чтобы в начале он включал незашифрованные байты, которые указывают длину или что-то еще.Кроме того, предположительно, есть другие люди, которые общаются с этим успешно, поэтому это должно быть возможно.

Ответы [ 3 ]

1 голос
/ 09 февраля 2012

При использовании криптосистемы с конкретным размером блока N каждый бит на выходе зависит от состояния по крайней мере N бит на входе.В случае многих современных систем, таких как AES, размер блока будет 128 или 256 бит (т.е. 16 или 32 байта).Хотя существуют схемы для шифрования файлов, длина которых не кратна размеру блока, не требуя заполнения (если, например, файл кратен 256 битам плюс дополнительные 32 бита, обычной схемой будет прекращение шифрования путем шифрованияблок, состоящий из последних 224 зашифрованных бит и оставшихся 32 незашифрованных бит), в общем случае невозможно зашифровать что-либо меньшее, чем блок.

Вам также придется зашифровать первые 16/32 байта вашего файла.используйте длину, а затем считайте «лишние» 12 или 28 байтов, которые вы читаете, как часть первого элемента данных, или же потребуйте, чтобы элементы данных имели минимальную длину 16 или 32 байта, и шифруйте их отдельно, оставляя длины незашифрованными.

1 голос
/ 09 февраля 2012

Мне удалось частично решить эту проблему (мой вопрос № 2) с помощью библиотеки BouncyCastle вместо встроенного класса .NET AES.

Сначала я попытался вручную дополнить зашифрованные данные с помощью PKCS7 (я считаю, что это единственная схема дополнения, поддерживаемая AES). Использование класса RijndaelManaged для этих дополненных вручную данных привело к исключению «Заполнение недопустимо и не может быть удалено». Поэтому я попытался использовать библиотеку BouncyCastle:

CfbBLockCipher cipher = new CfbBlockCipher(new AesEngine(), 128);
cipher.Init(false, new ParametersWithIV(new KeyParameters(key), iv));
cipher.DecryptBlock(encrypted, 0, decrypted, 0);

И это сработало отлично. Я не знаю, если это ошибка в .NET или что, но, надеюсь, это поможет всем, кто сталкивается с этим.

Теперь, если бы я только мог понять, как расшифровать эти первые четыре байта, чтобы я знал, как долго будет длиться сообщение ... (мой вопрос № 1)

Edit: Если я использую PaddedBufferBlockCipher BouncyCastle, я получаю ошибку "блок блок поврежден" при расшифровке. В этих данных есть что-то странное, что я могу расшифровать только вручную в одном блоке и только с помощью BouncyCastle (.NET TransformBlock просто дает мне нулевые байты для расшифрованного значения).

0 голосов
/ 09 февраля 2012

когда вы имеете дело с потоками TCP, вам обычно приходится буферизовать ваши данные в некоторой форме, если вы используете префикс длины, у вас есть фаза «Длина чтения», когда она читается, вы переключаетесь на «Чтение данных», когда эта длинавыполнено, вы передаете прочитанные байты и переключаетесь обратно на «Длительность чтения» ...

Помните, что вы можете не получать все, что отправляете, за одно чтение, или вы можете получить более одногоотправить за 1 чтение.

Зашифрована ли длина?Может ли быть так, что длина предваряется в незашифрованном виде, а затем полезные данные зашифрованы?... будет сложнее узнать, сколько читать, если вы не знаете, сколько читать, пока не расшифруете данные.

Предложить: 4 байта (есть другой метод) для длины зашифрованногоПолезная нагрузка

Чтение байтов до получения только что прочитанной длины.

(расшифровка полезной нагрузки)

4 байта ...

N байт ...

(Расшифровать)

Повторять при подключенном потоке.


Если у вас есть контроль над концом шифрования.

Функция получает входные байты Шифрование возвращает Encyptedбайты

Отправка зашифрованных байтов Длина (4 байта) Отправка зашифрованных байтов

Повторите для каждого входного блока.

...