Работа с GPG в проекте Netgap
Эта методичка описывает все сценарии работы с GPG в проекте Netgap: от создания личного ключа и его регистрации в проекте до подписи коммитов и релизов, проверки чужих подписей, резервного копирования, переноса ключа между машинами и шифрования переписки об уязвимостях.
GPG в Netgap — не факультативный инструмент, а основа модели доверия проекта:
- каждый коммит контрибьютора обязан быть подписан личным GPG-ключом (ADR 0004);
- каждый релиз обязан быть подписан maintainer отдельно по каждой платформе (ADR 0005);
- отчеты об уязвимостях принимаются только в зашифрованном виде (VDP).
Структура методички
Статьи расположены в порядке, в котором с ними сталкивается новый контрибьютор:
| Шаг | Статья | Что закрывает |
|---|---|---|
| 1 | Эта страница | Теория: как устроен GPG, какие бывают ключи и алгоритмы, как сделать осознанный выбор |
| 2 | Создание ключа и добавление в проект | Генерация ключа, получение key ID / fingerprint / публичного ключа, сертификат отзыва, регистрация в CONTRIBUTORS.json, публикация на сайте (authors.yml, WKD, gpg.asc) |
| 3 | Подпись и проверка коммитов | Настройка git, git commit -S -s, проверка своих и чужих подписей, повторная подпись после rebase, проверки CI |
| 4 | Подпись релизных артефактов | Подпись файлов хеш-сумм релиза, проверка подписи релиза на стороне CD и пользователем |
| 5 | Где взять ключ участника | WKD, gpg.asc, страница автора в блоге, сверка отпечатка с CONTRIBUTORS.json |
| 6 | Резервное копирование и перенос ключа | Бекап приватного ключа и сертификата отзыва, перенос ключа между своими машинами |
| 7 | Шифрование и расшифровка сообщений | Зашифрованная переписка об уязвимостях: шифрование отчета исследователем, расшифровка и ответ со стороны PSIRT |
В конце каждой статьи есть чеклист — по нему удобно проверять, что ничего не пропущено.
Зачем GPG в проекте
Netgap — сетевой шлюз, зона ответственности которого доходит до безопасности изолируемых периметров. Поле author в git-коммите подделывается тривиально, а хеш-сумма без подписи доказывает только целостность файла, но не то, кто его опубликовал. Поэтому проект строит доверие на криптографических подписях конкретных людей, а не на учетных записях платформ или автоматике CI/CD.
Единый корень доверия — файл CONTRIBUTORS.json: за каждым контрибьютором закреплен pgp_key_id, и CI сверяет подписи коммитов и релизов именно с ним.
Немного теории
GPG, PGP и OpenPGP — что есть что
- OpenPGP — открытый стандарт (RFC 4880 и его развитие RFC 9580), описывающий форматы ключей, подписей и зашифрованных сообщений.
- PGP — исторически первая коммерческая реализация стандарта; сегодня слово используется как синоним технологии («PGP-ключ», «PGP-подпись»).
- GnuPG (GPG) — свободная реализация OpenPGP, консольная утилита
gpg. Именно она используется в проекте.
Проект требует GnuPG версии 2.1 или новее — только начиная с нее полноценно поддерживаются современные эллиптические кривые (Ed25519/Curve25519).
Для чего используется GPG
Один и тот же ключ покрывает три криптографические задачи:
| Задача | Что дает | Где применяется в Netgap |
|---|---|---|
| Подпись (signing) | Подтверждает, что данные созданы владельцем ключа и не изменялись | Подпись коммитов, тегов, файлов хеш-сумм релиза |
| Шифрование (encryption) | Данные может прочитать только владелец приватного ключа получателя | Отчеты об уязвимостях и переписка с PSIRT |
| Аутентификация (authentication) | Вход по SSH с GPG-ключом | В проекте не используется, приведено для полноты |
Как устроен ключ: первичный ключ и подключи
«GPG-ключ» — это на самом деле связка (keypair-цепочка): первичный ключ (primary key) и один или несколько подключей (subkeys). У каждого ключа есть флаги назначения (usage flags):
C(certify) — сертификация: подпись собственных подключей и чужих ключей. Есть только у первичного ключа;S(sign) — подпись данных (коммиты, файлы);E(encrypt) — шифрование;A(authenticate) — аутентификация.
При генерации ключа по умолчанию (gpg --full-generate-key, вариант ECC sign + encrypt) создается именно такая связка: первичный ключ ed25519 с флагами [SC] и подключ cv25519 с флагом [E]. Этого достаточно для всех сценариев проекта. Например, ключ Lead Maintainer устроен так же — см. раздел 5 VDP.
К первичному ключу привязан UID — строка вида Имя Фамилия <email>. Email в UID важен: по нему работает WKD-автообнаружение ключа и по нему CI сопоставляет автора коммита с записью в CONTRIBUTORS.json.
Fingerprint, long key ID, short key ID
Ключ идентифицируется хешем публичного ключа:
| Идентификатор | Пример | Когда использовать |
|---|---|---|
| Fingerprint (40 hex-символов) | 6B83 5E5B B72C BC2A A35F 2E10 556B 4133 3653 BD5A | Единственный надежный способ сверить ключ. Всегда сверяйте именно его |
| Long key ID (последние 16 символов) | 556B41333653BD5A | Значение поля pgp_key_id в CONTRIBUTORS.json и authors.yml; аргумент команд gpg |
| Short key ID (последние 8 символов) | 3653BD5A | Не используйте: для short ID практически достижимы коллизии |
Какой алгоритм выбрать
Современный GnuPG предлагает несколько семейств алгоритмов. Осознанный выбор выглядит так:
| Алгоритм | Плюсы | Минусы | Рекомендация |
|---|---|---|---|
| Ed25519 + Curve25519 (ECC) | Короткие ключи и подписи, быстрые операции, современная криптография, устойчивость к ошибкам реализации | Не поддерживается очень старыми GnuPG (< 2.1) и некоторыми legacy-системами | Выбор по умолчанию для Netgap |
| RSA 4096 | Максимальная совместимость, включая старые смарт-карты и корпоративные системы | Длинные ключи и подписи, медленнее, при неудачном выборе параметров слабее эквивалентной ECC | Допустимо, если требуется совместимость с legacy-окружением |
| RSA 2048 | Совместимость | Нижняя граница допустимой стойкости, не подходит для долгоживущего ключа | Не рекомендуется для новых ключей |
| NIST P-256/384, Brainpool | Поддержка в отдельных корпоративных экосистемах | Нет преимуществ перед Ed25519 в контексте проекта | Не рекомендуется без особой причины |
Практический вывод: если нет жестких требований совместимости — создавайте ключ Ed25519/Curve25519. Именно такой сценарий описан в статье Создание ключа.
Срок действия и отзыв
- Ключу задается срок действия (expiration) — рекомендуется 1–2 года. Это страховка: даже если вы потеряете и приватный ключ, и сертификат отзыва, ключ «умрет» сам. Срок можно продлевать без замены ключа (
gpg --edit-key→expire) — публичный ключ после продления нужно переопубликовать. - Сертификат отзыва (revocation certificate) — заранее созданный файл, которым можно объявить ключ недействительным, даже не имея доступа к приватному ключу. Создается при генерации ключа автоматически и хранится офлайн — см. Резервное копирование.
- При компрометации или утере ключа действует организационная процедура: уведомление Lead Maintainer, отзыв ключа, замена
pgp_key_idвCONTRIBUTORS.json(ADR 0004, риски).
Модель доверия в проекте
Классический PGP предлагает «сеть доверия» (web of trust) — цепочки взаимных подписей ключей. Netgap использует более простую и строгую модель — прямое доверие через реестр проекта:
- источником истины по ключам контрибьюторов является
CONTRIBUTORS.jsonв репозитории; - любой полученный ключ (через WKD,
gpg.asc, keyserver и т. п.) обязательно сверяется по полному отпечатку с реестром; - CI автоматически сверяет подпись каждого коммита и релиза с
pgp_key_idсоответствующего участника.
Поэтому подписывать чужие ключи и выстраивать web of trust не требуется — достаточно аккуратной сверки отпечатков.
Быстрый старт: чеклист нового контрибьютора
- Установлен GnuPG ≥ 2.1 (
gpg --version). - Создан ключ Ed25519/Curve25519 со сроком действия 1–2 года — Создание ключа.
- Сертификат отзыва и резервная копия приватного ключа сохранены офлайн — Резервное копирование.
- Fingerprint и публичный ключ переданы Lead Maintainer,
pgp_key_idвнесен вCONTRIBUTORS.json— Создание ключа. - Git настроен на подпись:
user.signingkey,commit.gpgsign— Подпись коммитов. - Тестовый коммит подписан и проверен локально (
git log --show-signature).