Контрольные суммы
sha256sum, md5sum и родственники — посчитать хеш, проверить файлы по списку, почему MD5 не для защиты
Контрольная сумма (хеш) — короткая строка, которая меняется при изменении хотя бы одного байта файла. По ней проверяют, что файл скачался целиком и не подменён, и находят изменившиеся файлы. В coreutils для каждого алгоритма своя команда с одинаковыми опциями: sha256sum, sha512sum, sha1sum, md5sum, b2sum.
Синтаксис
sha256sum [опции] [файл…] # посчитать
sha256sum -c [опции] список # проверить по списку
Без файла (или с -) читает stdin.
Формат вывода
5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 a.txt
Хеш в шестнадцатеричном виде, два пробела, имя файла. Если между ними * вместо второго пробела (… *a.txt) — файл читался в «бинарном режиме»; в Linux разницы нет. Такие строки, сохранённые в файл, и есть список для -c. Для stdin вместо имени печатается -.
Опции при подсчёте
| Опция | Что делает |
|---|---|
--tag | формат BSD: SHA256 (a.txt) = … — сразу видно алгоритм |
-b / -t | бинарный / текстовый режим; в GNU/Linux результат одинаковый, меняется только * в выводе |
-z | завершать строки нулевым байтом вместо \n |
Опции при проверке (-c)
| Опция | Что делает |
|---|---|
-c список | для каждой строки пересчитать хеш файла и сравнить: имя: OK или имя: FAILED |
--quiet | не печатать OK, только ошибки |
--status | ничего не печатать; результат — только код выхода |
--ignore-missing | молча пропускать файлы, которых нет на диске |
--strict | ненулевой код выхода, если в списке есть кривые строки |
-w | предупреждать о каждой кривой строке с номером |
Код выхода -c: 0 — всё совпало, 1 — есть несовпадения, отсутствующие файлы или ошибки чтения.
Алгоритмы
| Команда | Длина хеша | Для чего годится |
|---|---|---|
md5sum | 32 hex-символа | быстрая проверка от случайной порчи; не для защиты |
sha1sum | 40 | устаревший, коллизии найдены; встречается в старых списках и в git |
sha256sum | 64 | стандарт по умолчанию для проверки загрузок |
sha512sum | 128 | то же семейство SHA-2, длиннее |
b2sum | 128 | BLAKE2b: быстрый и стойкий |
Примеры
# хеш файла
sha256sum archive.tar.gz
# только хеш, без имени
sha256sum archive.tar.gz | cut -d' ' -f1
# хеш строки: echo без -n добавит перевод строки и хеш будет другим
printf '%s' 'hello' | sha256sum
# сохранить суммы набора файлов
sha256sum *.txt > SHA256SUMS
# проверить: все ли файлы на месте и не изменились
sha256sum -c SHA256SUMS
# в скрипте — только код выхода
sha256sum -c --status SHA256SUMS && echo 'всё цело'
# сверить файл с опубликованным хешем (между хешем и именем — два пробела)
echo '5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 a.txt' | sha256sum -c
# суммы всего дерева каталогов, отсортированные по имени
find data -type f -exec sha256sum {} + | sort -k2 > data.sums
# найти одинаковые файлы: одинаковый хеш = одинаковое содержимое
find . -type f -exec md5sum {} + | sort | uniq -w32 -D
Подводные камни
- MD5 и SHA-1 не для безопасности. Для них умеют строить коллизии: два разных файла с одинаковым хешем. От случайной порчи при копировании MD5 защищает, от намеренной подмены — нет. Для проверки загрузок бери SHA-256 и сверяй хеш, полученный из надёжного источника, а не с того же сервера, что и файл.
- Пароли хешами не хранят.
sha256sumслишком быстрый — перебор займёт минуты. Для паролей существуют bcrypt, scrypt, Argon2. - Пути в списке относительные — как их записали.
sha256sum -cнадо запускать из того же каталога, иначеFAILED open or read. - Кривые строки игнорируются. Строку не в формате
хеш имяпроверка пропустит с предупреждением и всё равно может вернуть0. Добавь--strict. - Перевод строки меняет хеш.
echo 'hello' | sha256sumиprintf 'hello' | sha256sumдают разные результаты. Так же действуют\r\nиз Windows и лишний пробел в конце. - Регистр hex-символов при проверке не важен, а алгоритм — важен: список от
md5sumвsha256sum -cдастno properly formatted checksum lines found. - Имена с переводом строки или обратным слешем экранируются, и строка вывода начинается с
\. Это нормально,-cтакие строки понимает.