linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Протоколы/gpg-pgp

kb/protocols ── Протоколы ── intermediate

GPG/PGP - подпись, шифрование, web of trust

GPG = open-source реализация OpenPGP. Пара ключей (RSA/ECDSA), публичный для verify/encrypt, приватный для sign/decrypt. keyring локально, web-of-trust между людьми. Используется в git-commit signing, package-signing (apt/rpm), email.

view as markdownaka: gpg, pgp, gnupg, openpgp, web-of-trust

Что есть OpenPGP

OpenPGP (RFC 4880), стандарт асимметричной криптографии для data в покое: подписи и шифрование. GPG (GnuPG), main FOSS-имплементация на Linux/macOS. Альтернативы: Sequoia-PGP (Rust, новый), RNP (для Thunderbird).

Назначение исторически:

  • Шифрованная email-переписка между людьми без CA
  • Подпись release-артефактов (tar.gz, deb, rpm)
  • Web of trust, доверие через подписанные публичные ключи

Сегодня:

  • Git-commit signing (git commit -S)
  • Package signing: APT-репо, RPM-репо, npm-publish
  • secrets-tool (pass) для хранения паролей
  • Sign tarball в release notes (исторически, для верификации)

Email-encryption практически вымерло, заменили Signal/Matrix.

Pair ключей

GPG-ключ, это связка: master-key (для подписи sub-keys) + N sub-keys (encryption, signing, authentication).

Алгоритмы:

  • RSA 4096, классика, совместимость со всеми
  • EdDSA Ed25519 для подписи, современный, faster, smaller
  • Curve25519 (ECDH) для encryption, современный

Default в новых GnuPG, Ed25519 + Curve25519.

Создать:

bash
gpg --full-generate-key
# interactive: выбрать тип, размер, expiry, name+email

Или non-interactive:

bash
gpg --batch --gen-key <<EOF
Key-Type: EDDSA
Key-Curve: ed25519
Subkey-Type: ECDH
Subkey-Curve: cv25519
Name-Real: Alice Example
Name-Email: alice@example.com
Expire-Date: 2y
Passphrase: ...
EOF

Просмотр:

bash
gpg --list-keys                     # публичные
gpg --list-secret-keys              # с приватными
gpg --list-keys --keyid-format LONG # 16-hex fingerprint

Fingerprint и keyID

Каждый ключ имеет:

  • Full fingerprint, 40 hex-символов (SHA1, 20 байт; или SHA256 в новых): EB42 3B25 14F1 6F5C ...
  • Long key ID, last 16 hex characters: EB423B2514F16F5C
  • Short key ID, last 8: 14F16F5C (опасно, легко сколлайдить в spoofing, НЕ использовать)

При импорте/верификации сравнивай по full fingerprint, а не по name/email/short-id.

Подпись (sign)

bash
# Detached-signature (отдельный файл .sig)
gpg --detach-sign release-1.2.tar.gz

▸release-1.2.tar.gz.sig

# Embedded
gpg --sign message.txt              # бинарный + signature внутри
gpg --clearsign message.txt          # ASCII-armor (читаемый)

Verify:

bash
gpg --verify release-1.2.tar.gz.sig release-1.2.tar.gz
# gpg: Good signature from "Alice <alice@example.com>"
# gpg: WARNING: This key is not certified with a trusted signature!

Warning «not certified», потому что ключ не в web-of-trust для тебя. Это ожидаемо при первом импорте, проверка identity ключа на тебе.

Шифрование (encrypt)

Ключевое: шифровать публичным ключом получателя:

bash
# Импортировать публичный ключ Боба
gpg --import bob-public.asc
# Зашифровать ему
gpg --encrypt --recipient bob@example.com message.txt

▸message.txt.gpg

# Боб расшифровывает своим приватным
gpg --decrypt message.txt.gpg

Можно зашифровать нескольким получателям одновременно:

bash
gpg --encrypt -r alice@... -r bob@... -r carol@... file

Internally, random session key (AES) + N copies этого session key, каждая зашифрована публичным ключом получателя.

Keyring

Локальное хранилище в ~/.gnupg/:

~/.gnupg/
  ├── pubring.kbx        # public keys
  ├── private-keys-v1.d/ # приватные (новый формат)
  ├── trustdb.gpg        # web-of-trust info
  └── gpg-agent.conf     # agent settings

Операции:

bash
gpg --import alice.asc                # импорт ключа
gpg --export alice@example.com > alice.asc      # экспорт public
gpg --export-secret-keys alice > alice-private.asc # backup приватного
gpg --delete-key alice@example.com    # удалить public
gpg --delete-secret-key ...           # удалить приватный

ASCII-armor (-a или --armor), base64-обёртка для plaintext- совместимости (email, pastebin):

-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----

Web of Trust

Концепция вместо CA: вы доверяете тому, кому доверяет тот, кому вы доверяете.

Когда Alice встречает Боба лично, проверяет его fingerprint, и подписывает его ключ своей подписью:

bash
gpg --sign-key bob@example.com
# затем выложить обновлённый ключ Боба обратно
gpg --send-keys --keyserver hkps://keys.openpgp.org BOB_KEY_ID

Bob теперь импортирует и видит подпись Alice. Кто-то третий, кто доверяет Alice, теперь будет доверять Bob'у через её подпись.

Уровни trust в gpg:

  • unknown, нет данных
  • never, явно не доверять (отзыв доверия)
  • marginal, требуется N таких подписей чтобы суммарно доверять
  • full, одной подписи достаточно
  • ultimate, свой собственный ключ

Минусы:

  • Заметно сложно для юзеров
  • Key-signing parties, вымершая практика
  • Большинство людей сегодня просто TOFU (trust on first use)
  • Заменено для большинства cases'ов на CA-style модели (sigstore/[[image-signing-cosign|cosign]], keyless через OIDC)

Keyservers

Раньше: загрузить публичный ключ на keyserver (hkps://pool.sks-keyservers.net), кто угодно скачал. Сейчас:

  • keys.openpgp.org, современный, valid email confirmation
  • keyserver.ubuntu.com, для Ubuntu PPA
  • GitHub, gh keys add, доступно на https://github.com/<user>.gpg
bash
gpg --keyserver hkps://keys.openpgp.org --recv-keys EB423B2514F16F5C
gpg --keyserver hkps://keys.openpgp.org --send-keys EB423B2514F16F5C
curl https://github.com/alice.gpg | gpg --import

Git commit signing

Самое массовое современное использование:

bash
# Один раз настроить
git config --global user.signingkey EB423B2514F16F5C
git config --global commit.gpgsign true
# Подписывать commit
git commit -S -m "fix bug"
# Подписывать tag
git tag -s v1.2.3 -m "Release 1.2.3"
# Verify
git log --show-signature
git verify-tag v1.2.3

GitHub/GitLab верифицируют подпись → значок «Verified» на commit'е. Защищает от identity spoofing (любой может закоммитить от Linus Torvalds <torvalds@...>).

Package signing

APT (Debian/Ubuntu):

  • Каждый репо подписывает Release файл своим GPG-ключом
  • APT хранит trusted keys в /etc/apt/trusted.gpg.d/
  • При apt update верифицирует подпись Release
bash
curl -fsSL https://download.docker.com/linux/debian/gpg | \
  sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg

RPM (RHEL/Fedora), то же, но через rpm --import:

bash
rpm --import https://packages.example.com/RPM-GPG-KEY-myrepo

Без подписи apt/dnf будет ругаться warning'ом или ошибкой.

Subkeys и offline master

Best practice:

  • Master key хранить offline (на USB, в сейфе, на YubiKey)
  • Subkeys для повседневного использования (Encrypt, Sign, Auth) на ноутбуке
  • Если subkey скомпрометирован, отозвать его, master целый

Создание subkey:

bash
gpg --edit-key alice@example.com
> addkey
> save

Экспорт только subkeys (без master):

bash
gpg --export-secret-subkeys alice@example.com > subkeys-only.asc
# на ноуте импортировать только это

Хранение на YubiKey/HSM:

bash
gpg --edit-key alice@example.com
> key 1
> keytocard           # перенести encryption-subkey на YubiKey

Revocation

Если приватный ключ утёрян/скомпрометирован, нужно опубликовать revocation certificate. Лучше сгенерить сразу при создании:

bash
gpg --output revoke.asc --gen-revoke alice@example.com

И сохранить в безопасном месте. При компрометации:

bash
gpg --import revoke.asc
gpg --keyserver hkps://keys.openpgp.org --send-keys EB423B...
# все, кто refresh'ит ключ, увидят revocation

GPG vs cosign vs Signed Commits

| | GPG | [[image-signing-cosign|cosign]] | git-signed-commits | |---|-----|--------|---------------------| | Identity | self-published key + WoT | OIDC-keyless | git config + GPG | | Поддержка signing | универсальна | только OCI artifacts | только git objects | | Когда выбрать | email, packages, file-sigs | container images, supply chain | git history integrity |

Когда что-то пошло не так

  • gpg: decryption failed: No secret key, у тебя нет приватного ключа для этого ciphertext. Проверь gpg --list-secret-keys и сверь key-id с gpg --list-packets file.gpg.
  • gpg: signature ... not made by ... key, подпись валидна но другим ключом. Проверь fingerprint sender'а.
  • Inappropriate ioctl for device при --gen-key в скрипте - pinentry хочет TTY. Установить GPG_TTY=$(tty) или использовать --pinentry-mode loopback --passphrase ....
  • gpg-agent не находит passphrase, gpg-connect-agent reloadagent /bye или kill старый agent.
  • apt update ругается NO_PUBKEY, не импортирован ключ репо, скачать с keyserver: apt-key adv --recv-keys (deprecated) или через signed-by в sources.list:
    deb [signed-by=/etc/apt/trusted.gpg.d/foo.gpg] http://repo ...
  • YubiKey не виден, gpg --card-status должен показать. Если нет, pcscd not running или USB permissions.
  • WoT trust score «marginal», нужно подписать ключ сначала (--sign-key) или поднять trust manually (--edit-key → trust).
  • Backup приватного ключа потеряли, все зашифрованные ему данные необратимо потеряны. Только revoke. Никакого «password reset» в asymmetric crypto.

§ команды

bash
gpg --full-generate-key

Создать новую пару ключей с интерактивным выбором алгоритма и expiry

bash
gpg --list-keys --keyid-format LONG

Все публичные ключи в keyring с long-id (16 hex - безопаснее short)

bash
gpg --detach-sign release.tar.gz

Создать .sig файл рядом с release - стандартный паттерн для tarball'ов

bash
gpg --verify release.tar.gz.sig release.tar.gz

Проверить подпись - Good signature + проверка fingerprint глазами

bash
gpg --export --armor alice@example.com > alice.asc

Экспортировать публичный ключ в ASCII - для отправки или upload в keyserver

bash
git config --global commit.gpgsign true && git config --global user.signingkey <KEYID>

Включить подпись всех git-commit'ов выбранным ключом - GitHub покажет Verified

bash
curl -fsSL https://example.com/gpg-key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/example.gpg

Современный способ добавления apt-репо с явной trust-key (вместо apt-key)

§ см. также

  • ssh-hardeningSSH hardening - закрытие сервераSSH hardening: ключи only (PasswordAuthentication no), отключить root-login, AllowUsers/AllowGroups, MaxAuthTries, fail2ban-jail на sshd. Опционально - нестандартный порт + Match-блоки для гостей.
  • smtp-mtaSMTP и MTA - доставка emailSMTP - текстовый протокол доставки почты. 25/tcp - server-to-server, 587 - submission (клиент с auth), 465 - implicit-TLS legacy. MX-запись в DNS, STARTTLS+SPF+DKIM+DMARC - стандартный набор.
  • image-signing-cosignCosign и подпись container images (sigstore)cosign подписывает container images. Sigstore = ekosistema: rekor (transparency log), fulcio (CA для keyless OIDC). Подписи хранятся как OCI-объекты рядом с image. Verify - часть admission control в k8s через policy-controller или Kyverno.
  • tls-certificatesTLS-сертификаты - X.509, цепочка доверия, Let's EncryptTLS cert - X.509 объект с public key + identity (CN/SAN) + подписью CA. Цепочка: leaf → intermediate → root (доверенный OS). Let's Encrypt = бесплатный CA через ACME (HTTP-01/DNS-01 challenge). В k8s - cert-manager.
  • secrets-managementУправление секретами - Vault, k8s Secrets, sealed-secretsСекреты не в git, не в env-vars в коде. Опции: HashiCorp Vault (универсал, dynamic creds), k8s Secrets (base64, нужен encryption- at-rest), sealed-secrets (commit-friendly), external-secrets (sync из cloud-vault).
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки