Курица / яйцо проблема: хэш файла (включая хэш) внутри файла! Возможно?

дело в том, что у меня есть файл, в котором есть место для метаданных. Я хочу сохранить хэш для проверки целостности в нем. Проблема в том, что как только я сохраняю хэш, файл и хэш вместе с ним меняются.

Я прекрасно понимаю, что это по определению невозможно с помощью односторонних криптографических методов хэша, таких как md5/sha.

Я также знаю о возможности контейнеров, которые хранят данные проверки, отделенные от содержимого, как zip & co.

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

Это не то, что я хочу.

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

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

Я действительно не так в математике, но не может ли быть какой-то действительно продвинутый экспоненциальный модуль полином циклического обратного отсчета, который делает это возможным?

а если нет ,то что (если есть) доказательство против него?

причина, по которой мне нужен tis, заключается в том, что я хочу (в конечном счете) хранить хэш вместе с файлами MP4. Это сложно, но другое решения не легко реализовать, как файл проходит через плохо desigend производственного конвейера...

6 ответов


Это можно сделать с помощью CRC, в некотором роде. То, что я сделал в прошлом, - это выделить 4 байта в файле в качестве заполнителя для CRC32, заполнив их нулями. Затем я вычисляю CRC файла.

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

(дальнейшие подробности возможны, но не в данный момент. Вы в основном необходимо вычислить (CRC_desired-CRC_initial) * 2-8*byte_offset в поле Galois, где byte_offset - количество байтов между байтами-заполнителями и концом файла.)


примечание: согласно комментариям @KeithS, это решение не должно предотвращать преднамеренное вмешательство. Мы использовали его в одном проекте как средство привязки метаданных во встроенной системе к исполняемому файлу, используемому для его программирования - сама встроенная система не имеет прямого знания файл(ы), используемый для его программирования, и, следовательно, не может вычислить CRC или хэш сам-для обнаружения непреднамеренного несоответствия между встроенной системой и файлом, используемым для ее программирования. (В более поздних системах я только что использовал UUIDs.)


конечно, это возможно, во множестве путей. Однако,он не может предотвратить преднамеренное вмешательство.

например,

hash(X) = sum of all 32-bit (non-overlapping) blocks of X modulo 65521. 

пусть

Z = X followed by the 32-bit unsigned integer (hash(X) * 65521)

затем

hash(Z) == hash(X) == last 32-bits of Z

идея здесь заключается в том, что любое 32-разрядное целое число, конгруэнтное 0 по модулю 65521, не будет влиять на хэш X. Тогда, поскольку 65521


нет, невозможно. Вы либо вы отдельный файл для хэшей ala md5sum, либо встроенный хэш только для части "данные" файла.


Я помню старую программу DOS, которая смогла встроить в текстовый файл значение CRC этого файла. Однако это возможно только с помощью простых хэш-функций.
Хотя теоретически вы можете создать такой файл для любой хэш-функции (при наличии достаточного времени или правильного алгоритма), злоумышленник сможет использовать точно такой же подход. Более того, у него был бы выбор: использовать именно ваш подход для получения такого файла или просто избавиться от чека.

Это означает что теперь у вас две проблемы вместо одной, и обе должны быть реализованы с одинаковой сложностью. Вам решать, стоит ли это того.

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


путь менеджер пакетов nix делает это при вычислении хэша вы делаете вид, что содержимое хэша в файле является некоторым фиксированным значением, таким как 20 x, а не хэш файла, то вы пишете хэш над этими 20 xи когда вы проверяете хэш, Вы читаете это и снова игнорируете его, притворяясь, что хэш был просто фиксированным значением 20 xхеширование

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

но если вы не используете такой метод является невозможным


Это зависит от твоего определения "гашиш". Как вы заявляете, очевидно, с любым псевдослучайным хэшем это было бы невозможно (в разумное количество времени).

столь же очевидно, что есть, конечно, тривиальные "хэши", где вы можете это сделать. Например, данные с нечетным числом бит, равным 1 хэшу до 00, и четным числом 1S хэша до 11. Хэш не изменяет нечетность / четность 1 бит, поэтому файлы хэшируются одинаково, когда их хэш включен.