PGP/GPG: шифрование и подпись

Классический инструмент, чтобы зашифровать письмо или подписать релиз — и не доверять при этом ни одному центру сертификации.

PGP (Pretty Good Privacy) — стандарт гибридного шифрования и цифровой подписи; GPG (GNU Privacy Guard) — его свободная открытая реализация в командной строке.

В отличие от TLS, где доверие идёт сверху от центров сертификации, PGP строит доверие горизонтально, между людьми. Это делает его удобным для шифрования почты, файлов и для подписи программ — например, дистрибутивы Linux и многие проекты подписывают релизы ключами GPG. Понимание PGP даёт базовую интуицию про асимметричную криптографию на практике: ключевые пары, шифрование под чужой публичный ключ и подпись своим приватным.

Зачем это знать защитнику

PGP/GPG до сих пор используется для проверки целостности скачанных файлов и пакетов, защищённой переписки и подписи коммитов. Уметь проверить подпись релиза — это защита от подмены: если файл на зеркале подменили, подпись не сойдётся. А разбор частых ошибок (доверие непроверенному ключу, утечка приватного ключа) учит, где именно эта схема ломается на практике.

Ключевые пары

У каждого участника две связанные части: публичный ключ (его раздают всем) и приватный ключ (он хранится в секрете и обычно защищён паролем-парольной фразой). Правило простое и зеркальное: шифруют под чужой публичный ключ (расшифровать сможет только владелец приватного), а подписывают своим приватным (проверить сможет любой по публичному).

# создать пару ключей (интерактивно спросит имя, почту, пароль)
gpg --full-generate-key

# посмотреть свои ключи и экспортировать публичный, чтобы раздать
gpg --list-keys
gpg --armor --export [email protected] > my_public_key.asc

Отпечаток ключа

Публичный ключ длинный, поэтому его узнают по короткому отпечатку (fingerprint) — хешу ключевого материала. Именно отпечаток сверяют при личной встрече, чтобы убедиться, что у вас настоящий ключ человека, а не подделка. Покажем идею отпечатка на стандартной библиотеке Python (настоящий GPG считает иначе, но принцип «хеш ключа → короткий отпечаток» тот же):

import hashlib

pubkey_material = b'fake-public-key-bytes-for-demo'
fpr = hashlib.sha256(pubkey_material).hexdigest().upper()
groups = ' '.join(fpr[i:i+4] for i in range(0, 40, 4))
print('Отпечаток (первые 40 hex):')
print(groups)

Вывод:

Отпечаток (первые 40 hex):
453F 6F8E 2FAF E4FE DB46 8A5A A8C3 65AF 25CD 5885

Шифрование почты и файлов

PGP использует гибридную схему: содержимое шифруется быстрым симметричным шифром на случайном сеансовом ключе, а сам сеансовый ключ шифруется публичным ключом получателя. Так получают и скорость симметрии, и удобство асимметрии. На практике это одна команда:

# зашифровать файл для получателя (под его публичный ключ)
gpg --encrypt --recipient [email protected] secret.txt
# получится secret.txt.gpg — прочитает только владелец приватного ключа

# расшифровать у себя (спросит пароль приватного ключа)
gpg --decrypt secret.txt.gpg > secret.txt

Подпись и проверка

Подпись решает обратную задачу: не спрятать содержимое, а доказать авторство и целостность. Автор хеширует данные и шифрует хеш своим приватным ключом — получается подпись. Любой проверяет её публичным ключом автора: совпало — файл подлинный и не изменён. Часто используют detached-подпись (отдельный файл .asc или .sig рядом с дистрибутивом):

# создать отделённую подпись релиза
gpg --armor --detach-sign release-v1.0.tar.gz   # -> release-v1.0.tar.gz.asc

# проверить подпись скачанного файла
gpg --verify release-v1.0.tar.gz.asc release-v1.0.tar.gz

Идею «подписал секретом — проверил тем же материалом» можно показать учебной имитацией через HMAC из стандартной библиотеки (в настоящем GPG это асимметричная подпись, но логика «совпало/не совпало» наглядна):

import hmac, hashlib

key = b'signing-secret'
msg = b'release-v1.0.tar.gz contents'
sig = hmac.new(key, msg, hashlib.sha256).hexdigest()
print('подпись:', sig[:32], '...')

# проверка: пересчитать и сравнить безопасным способом
ok = hmac.compare_digest(sig, hmac.new(key, msg, hashlib.sha256).hexdigest())
print('проверка подписи:', ok)

Вывод:

подпись: b2ea4560874fb7b9225a17cafe6c5dee ...
проверка подписи: True

Web of trust

Главная идея PGP — доверие без центрального органа. Вместо CA участники сами подписывают ключи друг друга: «я лично проверил, что этот ключ принадлежит Алисе». Если вы доверяете Бобу, а Боб подписал ключ Алисы, вы получаете повод доверять и ключу Алисы. Из таких связей складывается web of trust — сеть доверия. Гибкость её и сила, и слабость: схема ровно настолько надёжна, насколько добросовестно люди сверяют ключи перед подписью.

Как это работает под капотом

Зашифрованное сообщение PGP — это контейнер из нескольких пакетов: зашифрованный сеансовый ключ (по одному на каждого получателя), зашифрованные данные и, при подписи, пакет подписи с идентификатором ключа и алгоритмом хеширования. ASCII-armor (формат .asc) — это просто base64-обёртка с заголовками, чтобы бинарный ключ или сообщение можно было вставить в письмо текстом.

Как защититься

  • Сверяйте отпечаток до доверия. Не подписывайте и не доверяйте ключу, отпечаток которого вы не проверили лично или по надёжному каналу — иначе подмена ключа пройдёт незаметно.
  • Берегите приватный ключ. Он должен лежать только на вашей машине, под сильной парольной фразой; утечка приватного ключа сводит всю защиту на нет.
  • Сделайте сертификат отзыва. Заранее сгенерируйте revocation certificate — он позволит объявить ключ недействительным, если приватный ключ скомпрометирован или утерян.
  • Проверяйте подписи дистрибутивов. Перед запуском скачанного пакета сверяйте его подпись с публичным ключом проекта — это ловит подмену файла на зеркале.
  • Следите за сроком. Ставьте ключам срок действия и обновляйте их; «вечные» ключи опаснее при утечке.

Итоги

  • PGP/GPG — гибридная схема: шифруют под чужой публичный ключ, подписывают своим приватным.
  • Шифрование прячет содержимое почты и файлов; подпись доказывает авторство и целостность (особенно полезна detached-подпись релизов).
  • Доверие строится горизонтально через web of trust, без центров сертификации — и держится на честной сверке отпечатков.
  • Самые частые провалы — доверие непроверенному ключу и утечка приватного ключа; от них спасают сверка отпечатка и сертификат отзыва.
Проверьте себя
1. В схеме PGP под какой ключ шифруют сообщение и каким ключом его подписывают?
AШифруют своим приватным, подписывают чужим публичным
BШифруют под публичный ключ получателя, подписывают своим приватным ключом
CИ шифруют, и подписывают одним общим симметричным ключом
DШифруют под приватный ключ получателя, подписывают его публичным
2. Что такое web of trust в PGP?
AСписок доверенных центров сертификации, встроенный в GPG
BСеть доверия, где участники сами подписывают ключи друг друга, заменяя центральный орган
CПротокол обмена ключами по сети
DСервер, который хранит все приватные ключи пользователей