Готовил я как-то тесты для системы, один из модулей которой помимо всего остального вычислял значение хеш-функции для загружаемого файла. В ТЗ был прописан и необходимый алгоритм — ГОСТ Р 34.11-94. За эталон я взял значение хеша, посчитанного сторонней утилитой Rhash.
f86c9ecfb6e63726b35ebc79528d013d52b781e06e29d7eb0c9d1cb256efb7c1
Понимая, что функция вычисляется стандартной библиотекой, я больше для очистки совести отправил запрос, соответствующий загрузке файла в модуль. Но судьба человека полна неожиданностей. И стоит только расслабиться, как видишь нечто подобное:
964ba8755ca782ec3c5e0f98c93347f9b96d9f39cf5c7fdef43a23273fe8868a
Кто не прав — разработчик модуля или утилиты?
Оказалось, ни то, ни другое.
Дело в том, что ГОСТ Р 34.11-94 подразумевает использование параметров — так называемых узлов замены и стартового вектора хеширования. Но не регламентирует конкретные значения. Тем не менее в приложении к ГОСТ есть примеры данных значений и рекомендация:
использовать только в проверочных примерах для настоящего стандарта.
После изучения предметной области выяснилось, что существует два RFC. RFC 4357, в котором используются параметры, созданные «КриптоПро», и RFC 5831 с теми самыми значениями из ГОСТ. Rhash по умолчанию считает хеш по RFC 5831. Использование параметров «КриптоПро» необходимо явно указывать:
rhash --gost-cryptopro <Имя файла>
Казалось бы, проблема решена. Но, чтобы было еще интереснее, стандарт не определяет формат вывода хеша. А поэтому возникает вопрос с порядком байтов.
Для непосвященных — существует два основных способа представления данных. От старшего байта к младшему (Big-endian), и наоборот (Little-endian).
Рассмотрим пример. Для наглядности выделены байты.
Big-endian последовательность байт:
rhash --gost-cryptopro --gost-reverse <Имя файла>
8a86e83f27233af4de7f5ccf399f6db9f94733c9980f5e3cec82a75c75a84b96
Little-endian порядок:
rhash --gost-cryptopro <Имя файла>
964ba8755ca782ec3c5e0f98c93347f9b96d9f39cf5c7fdef43a23273fe8868a
Таким образом, противоречия нет — все вышеперечисленные значения, а также
rhash --gost --gost-reverse <Имя файла>
c1b7ef56b21c9d0cebd7296ee081b7523d018d5279bc5eb32637e6b6cf9e6cf8
соответствуют ГОСТ Р 34.11-94.
Ссылки:
Википедия
Подробное описание
Автор: Zyablick