Перейти к основному содержимому

Работа с 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-keyexpire) — публичный ключ после продления нужно переопубликовать.
  • Сертификат отзыва (revocation certificate) — заранее созданный файл, которым можно объявить ключ недействительным, даже не имея доступа к приватному ключу. Создается при генерации ключа автоматически и хранится офлайн — см. Резервное копирование.
  • При компрометации или утере ключа действует организационная процедура: уведомление Lead Maintainer, отзыв ключа, замена pgp_key_id в CONTRIBUTORS.json (ADR 0004, риски).

Модель доверия в проекте

Классический PGP предлагает «сеть доверия» (web of trust) — цепочки взаимных подписей ключей. Netgap использует более простую и строгую модель — прямое доверие через реестр проекта:

  1. источником истины по ключам контрибьюторов является CONTRIBUTORS.json в репозитории;
  2. любой полученный ключ (через WKD, gpg.asc, keyserver и т. п.) обязательно сверяется по полному отпечатку с реестром;
  3. 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).