Реализация MD5 в C для файла XML - PullRequest
0 голосов
/ 28 января 2010

Мне нужно реализовать контрольную сумму MD5 для проверки контрольной суммы MD5 в файле XML, включая все теги XML, которые были получены от нашего клиента. Длина полученной контрольной суммы MD5 составляет 32 байта шестнадцатеричных цифр.

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

Наше приложение реализовано на языке C. Пожалуйста, помогите мне, как это реализовать.

Спасибо

Ответы [ 5 ]

4 голосов
/ 28 января 2010

Это напрямую зависит от библиотеки, используемой для синтаксического анализа XML. Это сложно, однако, потому что вы не можете встроить MD5 в сам файл XML, так как после встраивания контрольной суммы внутрь, если вы делаете контрольную сумму только из определенных элементов. Как я понимаю, вы получаете MD5 самостоятельно? Он рассчитывается по всему файлу или только по тегам / содержимому?

Точные решения зависят от используемого кода.

На основании вашего комментария вам необходимо выполнить следующие шаги:

  • загрузить XML-файл (возможно, даже в виде простого текста) и прочитать MD5
  • замените MD5 в файле на ноль, запишите файл (или лучше в память)
  • запустить MD5 на чистых данных файла и сравнить его со значением, сохраненным до
1 голос
/ 28 января 2010

Не изобретайте велосипед, используйте проверенное решение: http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html

Между прочим, это была первая ссылка, которая появилась, когда я прогуглил "реализацию md5" .

1 голос
/ 28 января 2010

Существуют общедоступные реализации MD5, которые вы должны использовать вместо того, чтобы писать свои собственные.Я слышал, что версия Колина Пламба широко используется.

0 голосов
/ 08 сентября 2011

Ознакомьтесь с этими примерами того, как использовать стандарт XMLDSIG с .net

Возможно, вам следует рассмотреть возможность изменения настроек для сохранения пробелов.

0 голосов
/ 30 января 2010

Это довольно противно. Предлагаемый подход предполагает, что вам необходимо проанализировать XML-документ в нечто вроде дерева DOM, найти контрольную сумму MD5 и сохранить ее для дальнейшего использования. Затем вы должны заменить контрольную сумму на 0, прежде чем повторно сериализовать документ и вычислить его хэш MD5. Все это звучит выполнимо, но потенциально сложно. Основная сложность, которую я вижу, заключается в том, что ваша новая сериализация документа может не совпадать с оригинальной, и несущественные (для XML) различия, такие как использование одинарных или двойных кавычек вокруг значений атрибутов, добавленных разрывов строк или даже другой кодировки, заставить хэши отличаться. Если вы пойдете по этому пути, вам нужно будет убедиться, что ваше приложение и процедура, использованная для создания документа, в первую очередь, сделают одинаковый выбор. Для такого рода проблем канонический XML является стандартным решением (http://www.w3.org/TR/xml-c14n).

Однако я бы сделал что-то другое. Если вам повезет, будет довольно легко написать регулярное выражение, чтобы найти хеш MD5 в файле и заменить его на 0. Затем вы можете использовать это, чтобы получить хеш и заменить его на 0 в XML-файле перед повторным вычислением хеша. Это позволяет обойти все возможные проблемы с анализом, изменением и повторной сериализацией XML-документа. Чтобы проиллюстрировать это, я собираюсь предположить, что хеш '33d4046bea07e89134aecfcaf7e73015' живет в файле XML следующим образом:

<docRoot xmlns='some-irrelevant-uri>
  <myData>Blar blar</myData>
  <myExtraData number='1'/>
  <docHash MD5='33d4046bea07e89134aecfcaf7e73015' />
  <evenMoreOfMyData number='34'/>
</docRoot>

(который я назвал hash.xml), что MD5 должен быть заменен 32 нулями (чтобы хеш был правильным) и иллюстрировать процедуру в командной строке оболочки с использованием perl, md5 и bash. (Надеюсь, что перевести это на C не составит труда, учитывая наличие библиотек регулярных выражений и хеширования.)

Чтобы устранить проблему, сначала нужно найти хеш, который находится в файле:

perl -p -e'if (m#<docHash.+MD5="([a-fA-F0-9]{32})#) {$_ = "$1\n"} else {$_ = ""}' hash.xml 

(это работает, ища начало атрибута MD5 элемента docHash, учитывая возможные другие атрибуты, а затем захватывая следующие 32 шестнадцатеричных символа. Если он находит их, он вставляет их в магическую переменную $ _, если если не установить пустое значение $ _, для каждой строки будет напечатано значение $ _. В результате будет напечатана строка «33d4046bea07e89134aecfcaf7e73015».)

Затем вам нужно вычислить хеш файла с заменой на нули:

perl -p -e's#(<docHash.+MD5=)"([a-fA-F0-9]{32})#$1"000000000000000000000000000000#' hash.xml | md5

(где регулярное выражение почти такое же, но на этот раз шестнадцатеричные символы заменяются нулями, и печатается весь файл. Затем MD5 этого значения вычисляется путем передачи результата через программу хеширования md5. с небольшим количеством bash дает:

if [ `perl -p -e'if (m#<docHash.+MD5="([a-fA-F0-9]{32})#) {$_ = "$1\n"} else {$_ = ""}' hash.xml` = `perl -p -e's#(<docHash.+MD5=)"([a-fA-F0-9]{32})#$1"000000000000000000000000000000#' hash.xml | md5` ] ; then echo OK; else echo ERROR; fi

, который выполняет эти две маленькие команды, сравнивает выходные данные и печатает «OK», если выходные данные совпадают, или «ERROR», если они не совпадают. Очевидно, что это всего лишь простой прототип, и он написан не на том языке, я думаю, что он иллюстрирует самое простое решение.

Кстати, почему вы помещаете хеш в документ XML? Насколько я вижу, он не имеет никакого преимущества по сравнению с передачей хеша по боковому каналу (даже такого простого, как во втором файле с именем documentname.md5) и делает проверку хешей более сложной.

...