2012-02-08 3 views
2

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

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

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

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

+0

Я действительно не знаю ответа, но это связано с криптографическим дополнением. На самом деле можно шифровать неполные блоки блочным шифром без каких-либо накладных расходов. – usr

+0

Почему бы не дождаться оставшихся байтов? – sprinter252

+0

@usr yes Я думаю, что какой-то тип заполнения вручную поможет мне решить # 2, но я до сих пор не знаю, что делать с # 1. – Dennis

ответ

0

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

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

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

Предложить: 4 байта (есть другой метод) для Длина Encrypted Payload не

прочитанной Б до длины всего чтения были получены.

(Расшифровать полезная нагрузка)

... 4 байта

N Bytes ...

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

Повторите то время как поток соединен.


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

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

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

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

+0

Как вы расшифровываете ТОЛЬКО первые 4 байта (или все байты, предполагая, что я могу выяснить, сколько всего)? – Dennis

+0

В моем примере из 10-байтового сообщения все 10 байтов зашифрованы. Обычно я хотел бы прочитать первые 4 байта, чтобы определить количество оставшихся байтов, но первые 4 также зашифрованы. В идеале я хотел бы расшифровать эти байты, а затем прочитать оставшиеся байты на основе этого расшифрованного значения, а затем расшифровать оставшиеся.Но я не могу расшифровать всего 4 байта за раз (а не 6 или 10). – Dennis

+0

Вам действительно нужно зашифровать длину? –

1

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

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

1

Я смог частично решить этот вопрос (вопрос №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 I BouncyCastle в при дешифровке получить «поврежденный блок». С этими данными есть что-то странное, что я могу только расшифровать вручную в одном блоке и только с BouncyCastle (.NET TransformBlock просто дает мне нулевые байты для дешифрованного значения).

Смежные вопросы