🧩 Проверка подлинности файлов: GPG, хеши, подписи
📌 Зачем проверять файлы
Ты скачал архив с исходниками. Откуда ты знаешь, что его не подменили? Сервер могли взломать (как с vsftpd 2.3.4), зеркало могло быть фейковым, DNS мог перенаправить тебя на подставной сайт. Без проверки ты устанавливаешь кота в мешке с возможным бэкдором внутри.
Три уровня защиты:
- Хеш (SHA-256) — отпечаток файла. Доказывает, что файл не изменён, но не доказывает, кто его создал
- GPG-подпись — криптографическое доказательство авторства + целостности. Подделать без приватного ключа невозможно
- Подписанные коммиты/теги в Git — тот же принцип, но встроенный в систему контроля версий
Аналогия: хеш — это отпечаток пальца на конверте (видишь, что конверт не вскрывали). GPG-подпись — нотариальная печать (знаешь, кто запечатал, и что содержимое не менялось).
⚡ Хеши: быстрая проверка целостности
Что такое хеш
Хеш-функция берёт файл любого размера и выдаёт строку фиксированной длины. Изменение даже одного бита в файле полностью меняет хеш. Это односторонняя функция — из хеша нельзя восстановить файл.
SHA-256 — текущий стандарт. MD5 и SHA-1 считаются сломанными — для них можно подобрать коллизии (два разных файла с одинаковым хешем).
Как проверять
# Посчитать SHA-256 хеш файла
sha256sum файл.tar.gz
# Результат: 2a4bb16562e0d594c37b4dd3b426cb012aa8457151d4718a5abd226cef9be3a5 файл.tar.gz
# Сравнить с хешем, который опубликовал автор
# Вручную — глазами сверяешь строки
# Или автоматически через файл контрольных сумм:
sha256sum -c checksums.sha256
# Выведет: файл.tar.gz: OK или файл.tar.gz: FAILED
Проверка нескольких файлов сразу
Если автор предоставил файл контрольных сумм (обычно SHA256SUMS, checksums.sha256 или подобное):
# Файл SHA256SUMS содержит строки вида:
# abc123... file1.tar.gz
# def456... file2.tar.gz
# Проверяешь все файлы одной командой
sha256sum -c SHA256SUMS
# file1.tar.gz: OK
# file2.tar.gz: FAILED ← этот файл изменён!
Если автор не предоставил файл сумм, но ты хочешь сам создать контрольные суммы для архива с кучей файлов:
# Считаешь хеши всех файлов в директории рекурсивно
find ./project/ -type f -exec sha256sum {} \; > checksums.sha256
# Потом в любой момент проверяешь:
sha256sum -c checksums.sha256
Подводные камни хешей
Хеш сам по себе не защищает от подмены. Если атакующий контролирует сервер, он подменит и файл, и хеш рядом с ним. Ты скачаешь оба, сверишь — всё совпадёт. Именно поэтому нужна GPG-подпись: её подделать невозможно без приватного ключа автора.
🔐 GPG-подписи: доказательство авторства
Как работает GPG
GPG (GNU Privacy Guard) — реализация стандарта OpenPGP. Работает на паре ключей:
- Приватный ключ — хранится только у автора, им он подписывает файлы
- Публичный ключ — доступен всем, им ты проверяешь подпись
Когда автор подписывает файл, GPG создаёт цифровую подпись на основе содержимого файла + приватного ключа. Ты берёшь публичный ключ автора, подпись и файл — GPG математически проверяет, что всё сходится.
Аналогия: автор ставит восковую печать своим уникальным перстнем. У тебя есть слепок перстня (публичный ключ). Ты прикладываешь слепок к печати — если совпадает, письмо подлинное.
Пошаговая проверка
# 1. Установка GPG (обычно уже есть в Linux)
sudo apt install gnupg
# 2. Импорт публичного ключа автора
# Вариант A — с сервера ключей по ID:
gpg --keyserver keyserver.ubuntu.com --recv-keys 8660FD3291B184CDBC2F6418AA62EC463C0E751C
# Вариант B — из файла, скачанного с сайта автора:
gpg --import author-pubkey.asc
# Вариант C — с сервера ключей по email:
gpg --keyserver keyserver.ubuntu.com --search-keys author@example.com
# 3. Проверка подписи
# Обычно рядом с файлом лежит .asc или .sig файл:
gpg --verify файл.tar.gz.asc файл.tar.gz
Чтение результата
# ✅ Всё хорошо:
gpg: Good signature from "Chris Evans <chris@scary.beasts.org>"
# ❌ Файл подменён:
gpg: BAD signature from "Chris Evans <chris@scary.beasts.org>"
# ← Именно это произошло с vsftpd 2.3.4
# ⚠️ Подпись верна, но ключ не подтверждён:
gpg: Good signature from "Chris Evans <chris@scary.beasts.org>"
gpg: WARNING: This key is not certified with a trusted signature!
# Это значит: подпись математически верна, но ты не подтвердил,
# что публичный ключ действительно принадлежит этому человеку.
# Нужно сверить fingerprint ключа из независимого источника.
Проверка fingerprint
# Посмотреть fingerprint импортированного ключа
gpg --fingerprint author@example.com
# Выведет что-то вроде:
# 8660 FD32 91B1 84CD BC2F 6418 AA62 EC46 3C0E 751C
# Этот fingerprint нужно сверить с тем, что автор публикует
# на своём сайте, в Twitter, на конференциях и т.д.
# Если совпадает — ключ подлинный.
Подписанный файл контрольных сумм
Лучшая практика, которую используют крупные проекты (Debian, Tor, и др.):
# Автор создаёт файл с хешами всех файлов релиза
sha256sum *.tar.gz *.zip > SHA256SUMS
# Подписывает ЭТОТ файл своим ключом
gpg --armor --detach-sign SHA256SUMS
# Создаётся SHA256SUMS.asc
# Ты проверяешь:
# 1. Подпись файла сумм
gpg --verify SHA256SUMS.asc SHA256SUMS
# 2. Сами хеши файлов
sha256sum -c SHA256SUMS
Это решает проблему «много файлов в релизе» — подписывается один файл с хешами, а хеши покрывают все остальные файлы.
🔍 Git: подписанные коммиты и теги
Подписанные коммиты
На GitHub рядом с коммитом может быть зелёный бейдж "Verified". Это значит:
- Автор подписал коммит GPG, SSH или S/MIME ключом
- GitHub подтвердил, что подпись валидна и ключ привязан к аккаунту
# Посмотреть подписи коммитов в репозитории
git log --show-signature
# Вывод для подписанного коммита:
# gpg: Good signature from "Developer Name <dev@example.com>"
# Вывод для неподписанного:
# (просто коммит без информации о подписи)
Подписанные теги (релизы)
Теги — это метки на конкретных коммитах, обычно для релизов (v1.0, v2.3.4). Подписанный тег — более надёжный ориентир:
# Проверить подпись тега
git tag -v v2.3.4
# gpg: Good signature from "Author Name <author@example.com>"
Нюансы Git и GitHub
Отсутствие "Verified" — не всегда тревога. Многие разработчики просто не подписывают коммиты, потому что это дополнительный шаг. Но для критически важного софта (криптография, серверное ПО, инструменты безопасности) отсутствие подписей — повод задуматься.
"Verified" на GitHub — не абсолютная гарантия. Если аккаунт разработчика скомпрометирован, атакующий может загрузить свой GPG-ключ в настройки аккаунта и подписывать коммиты им. Бейдж будет зелёным. Поэтому для параноидальной проверки нужно сверять fingerprint ключа из независимого источника, а не просто доверять GitHub.
git clone и подмена. Когда ты клонируешь репозиторий, Git проверяет целостность объектов через SHA-хеши. Но если ты качаешь архив (Download ZIP на GitHub) — это просто файл, без Git-метаданных и подписей. Безопаснее клонировать через git clone и проверять теги.
🛡 Что делать, если в архиве много файлов
Три сценария:
Сценарий 1: Автор предоставил подписанные хеши
Лучший случай. Делаешь как описано выше — gpg --verify подписи, затем sha256sum -c хешей.
Сценарий 2: Есть только хеш самого архива
# Проверяешь хеш архива целиком (не отдельных файлов внутри)
sha256sum project-v1.0.tar.gz
# Сравниваешь с опубликованным хешем
# Если совпал — все файлы внутри тоже не тронуты,
# потому что изменение любого файла меняет хеш архива
Это работает, потому что хеш считается от всего архива как единого бинарного блоба. Если внутри изменён хоть один байт одного файла — хеш всего архива будет другим.
Сценарий 3: Нет ни подписей, ни хешей
# Скачиваешь из нескольких независимых источников и сравниваешь
sha256sum source1/project.tar.gz source2/project.tar.gz
# Если хеши совпадают — скорее всего, файл не подменён
# (атакующий вряд ли контролирует все зеркала одновременно)
# Для Git-проектов — клонируешь репозиторий и собираешь из него:
git clone https://github.com/author/project.git
cd project
git checkout v1.0
git log --show-signature -1
🧰 Практический чеклист
Перед установкой софта из исходников
# 1. Скачай файл и подпись/хеш
wget https://example.com/soft-1.0.tar.gz
wget https://example.com/soft-1.0.tar.gz.asc # подпись
wget https://example.com/SHA256SUMS # хеши (если есть)
# 2. Импорт ключа автора (если ещё нет)
gpg --keyserver keyserver.ubuntu.com --recv-keys KEY_ID
# 3. Проверь подпись
gpg --verify soft-1.0.tar.gz.asc soft-1.0.tar.gz
# 4. Если есть файл хешей — проверь и его
gpg --verify SHA256SUMS.asc SHA256SUMS # если подписан
sha256sum -c SHA256SUMS
# 5. Только после "Good signature" + "OK" — распаковывай и собирай
tar xzf soft-1.0.tar.gz
cd soft-1.0/
./configure && make && sudo make install
Команды на каждый день
# Быстрый хеш файла
sha256sum файл
# Хеши всех файлов в директории
find . -type f -exec sha256sum {} \; > checksums.sha256
# Проверка по файлу сумм
sha256sum -c checksums.sha256
# Проверка GPG-подписи
gpg --verify файл.sig файл
# Git: проверить подпись последнего тега
git tag -v $(git describe --tags --abbrev=0)
# Git: лог с подписями
git log --show-signature -5
🧠 Готовые комбо
Скачал .tar.gz + .asc с сайта проекта →
gpg --recv-keys KEY_ID → gpg --verify file.tar.gz.asc file.tar.gz → ждёшь "Good signature" → распаковываешь
Клонируешь репо с GitHub →
git clone URL → git tag -v TAG → проверяешь подпись тега → собираешь из подписанного коммита
Нет подписей, только хеш на сайте →
sha256sum file → сверяешь глазами с сайтом → качаешь с зеркала → сверяешь хеши между собой
Хочешь защитить свои файлы →
sha256sum * > SHA256SUMS → gpg --armor --detach-sign SHA256SUMS → публикуешь оба файла рядом с релизом
⚠️ Важные моменты
- MD5 и SHA-1 — мертвы для безопасности. Используй только SHA-256 или выше. MD5 ломается за секунды, SHA-1 — за часы/дни
- Хеш без подписи — полумера. Атакующий, контролирующий сервер, подменит и файл, и хеш. GPG-подпись решает эту проблему
- Первый импорт ключа — момент доверия. Если ты импортируешь ключ автора и не сверяешь fingerprint из независимого источника, атакующий мог подсунуть свой ключ. Сверяй fingerprint через Twitter, блог автора, Keybase, конференции
- Пакетные менеджеры (apt, dnf, pacman) делают это за тебя. Репозитории дистрибутивов подписаны ключами мейнтейнеров. Когда ты ставишь софт через
apt install— подписи проверяются автоматически. Проблема возникает, когда качаешь напрямую с сайта проекта - GitHub "Verified" ≠ абсолютное доверие. Это доверие аккаунту GitHub, а не личности. Если аккаунт взломан — бейдж обманет. Для критичного софта сверяй GPG fingerprint отдельно
- Download ZIP на GitHub — без подписей. Всегда лучше
git clone+ проверка тегов, чем скачивание архива через кнопку