Хаос данных из-за многократного шифрования / дешифрования

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

Сначала я подумал, что могу просто удалить нулевые байты после каждого процесса дешифрования, чтобы получить исходные данные перед заполнением. Теперь, если данные имеют несколько нулевых байтов на самом конце, то удаление нулевых байтов после процесса дешифрования просто удалит части исходных данных и закончится потерей данных и, возможно, неправильной расшифровкой (последняя точка зависит от размера блока следующих алгоритмов дешифрования). Хотя вероятность того, что данные или данные после нескольких процессов шифрования содержат несколько нулевых байтов, почти равна нулю, я ищу решение для решения проблемы, описанной выше.

Если я не хочу удалять нулевые байты из данных, я также получу некоторые раздражающие результаты в зависимости от размеров блоков используемых алгоритмов. Чтобы показать, что я написал программу на Python, которая имеет три криптографических алгоритма, один работает с размером блока 2 байта, другой работает с размером блока 3, а последний имеет размер блока 4, поэтому вы можете сравнить их с 128-, 192- и 256-битные алгоритмы. Я начал с нескольких случайных байтов и несколько раз зашифровал их, а затем расшифровал, не удаляя нулевые байты после каждого процесса дешифрования. Программа печатала байты после каждого процесса дешифрования / шифрования в шестнадцатеричном формате, вот результат с некоторыми комментариями от меня:

48 61 6c 6c 6f                      //thats our data at the start
da b4 28 fe 9e 4a                   //now the 3-byte algorithm was run -> padded to 6 bytes
5e 62 04 72 1a d8 d2 a4             //used the 4-byte algorithm -> padded to 8 bytes
cc a1 43 e0 f5 e7 40 eb 81          //3-byte algorithm used again -> padded to 9 bytes
48 61 7a 07 71 1e 3f 0f 05 8d 98 a4 //at last used the 4-byte algorithm -> padded to 12 bytes
cc a1 43 e0 f5 e7 40 eb 81 00 00 00 //first encryption done, notice the three null-bytes and the similarity to line 4
5e 62 04 72 1a d8 d2 a4 00 92 0f 2a //secound encryption done, not removed null-bytes "decrypted", but the rest goes well, as seen in line 3
da b4 28 fe 9e 4a 00 00 84 1a 8d 03 //third encryption done, same as above, decryption of null-bytes results in chaos, but original data still the same
48 61 6c 6c 6f 00 92 0f ae 88 98 be //last encryption, we got original data with some near random bytes

Вы можете видеть, что первый процесс дешифрования идет хорошо, второй тоже, за исключением трех байтов заполнения, которые «расшифровываются». Итак, после каждого процесса шифрования мы приближаемся к нашим исходным данным, но продолжаем расшифровывать эти байты заполнения. (Примечание: если кто-то сомневается в моих функциях шифрования / дешифрования, я тестировал их несколько 100 раз, и они работали каждый раз, я также могу опубликовать исходный код, если требуется или сомневаюсь)

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


person Sirac    schedule 05.03.2014    source источник
comment
Шифр с размером блока 2 байта звучит ужасно слабо. Полагаю, это не производственный код?   -  person ntoskrnl    schedule 05.03.2014
comment
Я просто использовал это, чтобы описать свою проблему, результат будет таким же с размером блока 16, 24 или 32 байта, но мой образец вывода был бы намного больше   -  person Sirac    schedule 06.03.2014
comment
В этом случае см., Например, этот вопрос и это сообщение в блоге.   -  person ntoskrnl    schedule 06.03.2014


Ответы (1)


Вместо заполнения данных нулями вы можете использовать режим заполнения, такой как PKCS # 7, который кодирует величину заполнения в самих байтах заполнения. Это позволяет определить количество байтов заполнения при расшифровке, чтобы их можно было удалить, оставив только исходный открытый текст.

По сути, все байты заполнения равны количеству добавленных байтов заполнения. Например. если требуется 3 байта заполнения, то заполнение будет 3 байта 0x03.

Существует всегда по крайней мере один байт заполнения, это означает, что если открытый текст уже кратен размеру блока, то должен быть добавлен дополнительный блок, состоящий только из заполнения. Это гарантирует, что можно отличить открытый текст, который в точности кратен размеру блока и который уже заканчивается n байтами из n, и открытый текст, заполненный n байтами.

person Iridium    schedule 05.03.2014
comment
Спасибо, этот вопрос подарил мне бессонную ночь, и почему-то я не мог придумать решение, которое было бы легко - person Sirac; 05.03.2014