- Пространство для экспериментов
- Всё и сразу
- Идеология и концепты OpenPGP
- Ключи
- Распространение открытого ключа
- Редактирование ключа
- Управление ключами
- Защита данных
- Что осталось за рамками статьи
- Полезное дополнительное чтиво
Здесь написано о GnuPG, как им пользоваться и при этом понимать, что делаешь. Изначально статья была написана в 2013 году, несколько раз слегка обновлялась, а в 2023 была значительно переработана и дополнена актуальной информацией.
GnuPG (GNU Privacy Guard, официальный сайт gnupg.org) — это опенсорсная реализация открытого стандарта OpenPGP, изложенного в RFC 4880. GnuPG состоит из набора программ и библиотек, однако нас будет интересовать только консольная программа gpg. Она существует под все операционные системы, однако наиболее комфортно используется в linux и macos. По gnupg есть множество материалов, однако из-за высокой сложности базовых концептов, всегда есть что добавить или объяснить.
В линуксах gnupg ставится из штатного репозитория, для макоси можно поставить из macports, brew, но я рекомендую GPG Suite. Все эти способы предоставляют вам консольную программу gpg с одинаковыми командами на всех операционках. Текущая актуальная версия GnuPG 2.2 и вся статья отталкивается именно от неё. Многие команды в принципе применимы и для более старых версий.
Между разными версиями gnupg формат хранения данных в каталоге с конфигурацией несколько раз менялся и связанные с этим термины типа keyring уже во многом устарели, поэтому в обновлённой версии я постараюсь не углубляться в конкретные детали реализации и слова типа keyring/кейринг тут использоваться не будут. Чтобы подчеркнуть относительность конфигурации, я буду использовать слово конфиг, под которым вы должны понимать выбранный каталог с конфигурацией. Также я не буду вдаваться в эзотерические команды или свойства подписей, который никем нигде не используются.
Когда я рассказываю о концепциях, то обычно использую термин OpenPGP, когда рассказываю о конкретных прикладных командах, то использую gpg или gnupg.
Пространство для экспериментов¶
Все свои данные GnuPG хранит в отдельном каталоге, по умолчанию это ~/.gnupg/
, однако для экспериментов лучше создать новый пустой, чтобы не потерять данные из главного (если он у вас есть). Пусть это будет ~/gnupg-test/
, а для удобства вот команда в shell для создания алиаса (псевдонима):
$ alias gpg="/usr/bin/gpg --homedir=~/gnupg-test"
Теперь вы можете выполнять все описанные ниже команды и не бояться, что они затронут главный каталог. Если у вас macos, то вместо /usr/bin/gpg
укажите свой путь, его можно узнать через команду whereis gpg
.
И команда для удаления алиаса:
$ unalias gpg
Всё и сразу¶
Короткая выжимка основных операций. Подробности в разделах ниже. Каждая команда дана в двух эквивалентных вариантах: с короткими и длинными аргументами.
Шифруем файл GPL.txt
открытым ключом (моим), результат записывается в GPL.txt.gpg
:
$ gpg -e -r [email protected] GPL.txt
$ gpg --encrypt --recipient [email protected] GPL.txt
Расшифровываем присланный файл и записываем результат в файл GPL.txt
:
$ gpg -o GPL.txt -d GPL.txt.gpg
$ gpg --output GPL.txt --decrypt GPL.txt.gpg
Создаём цифровую подпись (т.е. подписываем) файл GPL.txt
, подпись создаётся в отдельном файле GPL.txt.sig
(т.н. отсоединённая подпись, detached signature), в аргументе -u [email protected]
указываем, какой ключ использовать:
$ gpg -u [email protected] --detach-sign GPL.txt
Вместо --detach-sign
можно писать -b
:
$ gpg -u [email protected] -b GPL.txt
Ещё можно сделать цифровую подпись вместе с самим документом, это делается такой командой (подпись записывается в файл GPL.txt.gpg
):
$ gpg -u sergei -s GPL.txt
$ gpg --local-user sergei --sign GPL.txt
Полученный на прошлом шаге файл GPL.txt.gpg
вместе с подписью содержит и сам документ, его можно извлечь такой командой:
$ gpg --output GPL.txt --decrypt GPL.txt.gpg
А чтобы просто проверить подпись документа, делаем так (это внешняя подпись, поэтому для корректной проверки рядом должен лежать файл GPL.txt
):
$ gpg --verify GPL.txt.sig
Если сам файл для проверки именуется по-другому, можно просто указать его имя в команде:
$ gpg --verify GPL.txt.sig lincense.txt
Идеология и концепты OpenPGP¶
Концептуально OpenPGP представляет собой крайне сложную для понимания систему понятий и действий. Поскольку OpenPGP не навязывает какой-либо конкретный сценарий использования, его конкретные реализации очень легко можно использовать небезопасно. И даже если вы понимаете все концепты, то даже в такой ситуации не застрахованы от ошибки из-за большой гибкости инструментов.
При использовании gnupg буквально заваливает вас тоннами различных предупреждений и сообщений, степень важности которых неочевидна. И наоборот, в критичных ситуациях нет сообщений, предупреждающих о небезопасности действия. Пример последнего — расшифровка файла без дополнительной подписи.
Продвигаемая в OpenPGP система доверия Web of trust является более гибкой, чем традиционная PKI (public key infrastructure) с делегированием проверки на удостоверяющие центры в TLS, например. Однако эта гибкость даётся ценой очень высокой концептуальной сложности и требованием тщательного изучения концептов. В результате идеи и реализации OpenPGP широкого распространения не получили даже в корпоративной среде, где, в теории, такой подход был бы очень полезен.
Ключи¶
Главный компонент OpenPGP — ключ. В рабочей конфигурации обычно хранится несколько ключей: ваш собственный и чужие ключи. Каждый ключ состоит из двух частей: обязательной открытой и опциональной закрытой. Закрытая хранится только у владельца ключа в зашифрованном виде. Открытая распространяется свободно в интернете.
закрытая часть используется для:
- подписывания/удостоверения данных;
- дешифрования зашифрованных файлов.
Закрытый ключ зашифрован симметричным алгоритмом и при его использовании нужно вводить пароль (парольную фразу), которым ключ зашифрован в хранилище.
Открытая часть используется для:
- проверки подписи данных;
- шифрования данных.
❈ ❈ ❈
В закрытой части хранятся закрытые криптоключи, в открытой соответственно открытые криптоключи.
И это действительно важный момент.
Дальше в тексте я буду явно разделять по смыслам слова ключ и криптоключ. Ключ — это такая собирательная сущность OpenPGP/gnupg, объединяющая несколько криптоключей, подписи, identity пользователей и т.п. А криптоключ — это бинарные данные, непосредственно использующиеся в криптоалгоритмах для операций типа подписывания или шифрования.
Криптоключ имеет как минимум открытую часть, а иногда и закрытую. Пара открытый-закрытый криптоключ называется ключевой парой.
Таким образом, если вы хотите кому-то отправить зашифрованный текст, который получатель сможет расшифровать, вы берёте открытый криптоключ этого пользователя, шифруете этим ключом данные. Получатель берёт у себя закрытую компоненту криптоключа и расшифровывает.
Если вы хотите подтвердить/удостоверить подлинность текста, берёте свой закрытый криптоключ, вычисляете при помощи него и первоначального текста специальный набор байтов, называемый электронной подписью, и отправляете подпись вместе с документом. Получатель берёт ваш открытый криптоключ, текст и подпись, скармливает это всё специальному алгоритму, который говорит: «да, эта подпись соответствует этому открытому криптоключу для этого текста». Таким образом получатель может быть уверен, что он получил точно тот же документ, который вы ему отправили.
❈ ❈ ❈
Центральной частью OpenPGP-ключа является мастер-криптоключ, который служит для подтверждения и удостоверения принадлежности данных внутри ключа. Например, все дополнительные крипто-ключи внутри OpenPGP-ключа (их называют подчинёнными ключами/subkeys) подписаны мастер-ключом, чтобы удостоверить их принадлежность. Мастер-криптоключ обычно используется только для подписывания, а для шифрования создаются отдельные подчинённые криптоключи.
Помимо криптоключей в OpenPGP-ключе могут находиться и другие блоки данных: информация об именах пользователей (identity), электронные подписи, даже фотографии.
В рабочей конфигурации gnupg обычно хранится один ваш ключ и несколько ключей других людей или организаций. У сторонних ключей тоже есть мастер-криптоключ, только без закрытой части.
❈ ❈ ❈
Новый OpenPGP-ключ (состоящий из мастер-криптоключа с закрытой частью и криптоключа для шифрования данных тоже с закрытой частью) можно создать такой командой:
$ gpg --gen-key
В процессе вам предложат ввести своё имя, e-mail и пароль для шифрования закрытой части. Весь диалог выглядит примерно так (здесь и далее в листингах полужирным шрифтом показаны вводимые пользователем данные):
gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. gpg: keybox '/home/serge/gnupg-demo/pubring.kbx' created Note: Use "gpg --full-generate-key" for a full featured key generation dialog. GnuPG needs to construct a user ID to identify your key. Real name: Sergey Stolyarov Email address: [email protected] You selected this USER-ID: "Sergey Stolyarov" Change (N)ame, (E)mail, or (O)kay/(Q)uit? O We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. gpg: /home/serge/gnupg-demo/trustdb.gpg: trustdb created gpg: directory '/home/serge/gnupg-demo/openpgp-revocs.d' created gpg: revocation certificate stored as '/home/serge/gnupg-demo/openpgp-revocs.d/57F80A6420E2B1CA6F990F04BB9152FD77C92BB6.rev' public and secret key created and signed. pub rsa3072 2023-07-05 [SC] [expires: 2025-07-04] 57F80A6420E2B1CA6F990F04BB9152FD77C92BB6 uid Sergey Stolyarov sub rsa3072 2023-07-05 [E] [expires: 2025-07-04]
По умолчанию ключ создаётся с датой окончания плюс два года от текущей. Вы можете выбрать другой срок или создать ключ без ограничения срока действия. При необходимости вы можете этот срок продлить, однако выпускать ключ без даты окончания не рекомендуется, так как если вы забудете парольную фразу или потеряете доступ, этот ключ будет бесконечно циркулировать и считаться действующим.
Идентификация ключей¶
При работе с gpg нужно указывать, какой именно ключ вы хотите использовать, поскольку в рабочей конфигурации их как правило хранится несколько. Как минимум это ваш ключ (закрытая и открытая части), плюс ключи других людей. Первый способ идентификации — через отпечатки (fingerprint) его криптоключей.
По сути отпечаток криптоключа — это набор байтов, который строится на основе байтов открытой части криптоключа (хеш-сумма плюс дополнительные байты). Отпечаток мастер-криптоключа считается отпечатком всего OpenPGP-ключа. Идентификатор (ID) ключа строится из отпечатка следующим образом (для читаемости я разбил на сегменты по 4 символа):
- отпечаток:
57F8 0A64 20E2 B1CA 6F99 0F04 BB91 52FD 77C9 2BB6
- короткий идентификатор (short ID):
77C9 2BB6
, последние 32 бита отпечатка - длинный идентификатор (long ID):
BB91 52FD 77C9 2BB6
, последние 64 бита отпечатка
❈ ❈ ❈
Помимо отпечатка, вы можете использовать хранимую в ключе информацию о пользователях (identity): имя, часть имени, e-mail, файл с фотографией и так далее. Программа gpg достаточно умная и способна найти ключ, например, лишь по части полного имени.
Поэтому, если у вас в конфиге есть открытый ключ, в пользователях (identity) которого есть емейл [email protected]
и вы хотите отправить ему зашифрованный текст, можно команду зашифровки файла test.txt
набрать так:
$ gpg -o test.txt.encrypted -r [email protected] -e test.txt
Здесь в параметре -r [email protected]
указывается e-mail получателя (-r
означает recipient). Вместо e-mail можно указать ID конкретного ключа, или полное имя, или только имя, или фамилию — gpg почти всегда что-то да найдёт, что введённому тексту соответствует.
❈ ❈ ❈
Если вы хотите подписать файл ~/tmp/test.txt
(создать цифровую подпись), то это можно сделать так:
$ gpg -u [email protected] -s ~/tmp/test.txt
You need a passphrase to unlock the secret key for
user: "John Smith (esquire) <[email protected]>"
2048-bit RSA key, ID 4600813F, created 2013-03-11
Enter passphrase:
Здесь имя передаётся в команде -u [email protected]
. Цифровая подпись будет создана в файле ~/tmp/test.txt.gpg
.
В одних командах для указания ключа используется команда
-u
(когда используется закрытый ключ), в других —-r
(когда используется открытый ключ).
Открытый ключ¶
Сразу начнём со списка:
$ gpg --list-keys
/home/serge/gnupg-demo/pubring.kbx
------------------------------------------------------
pub rsa3072 2023-07-05 [SC] [expires: 2025-07-04]
57F80A6420E2B1CA6F990F04BB9152FD77C92BB6
uid [ultimate] Sergey Stolyarov <[email protected]>
sub rsa3072 2023-07-05 [E] [expires: 2025-07-04]
Если у вас свежий конфиг с одним ключом, то после выполнения команды вы получите у себя в терминале нечто подобное. На примере этого листинга объясню базовые вещи о структуре gnupg-ключа.
Команда --list-keys
печатает список всех открытых частей ключей. Каждый ключ отделяется пустой строкой от следующего и состоит из нескольких блоков данных, каждый блок1 в листинге печатается в отдельной строке. В одном ключе скрывается сразу несколько криптоключей, которые используются в разных ситуациях (например, один криптоключ используется для подписывания, другой — для шифрования). Помимо криптоключей, в блоках ключа хранятся и другие данные (о них будет написано ниже).
Начнём с первого блока:
pub rsa3072 2023-07-05 [SC] [expires: 2025-07-04]
57F80A6420E2B1CA6F990F04BB9152FD77C92BB6
Первая строка начинается с pub
и в ней указываются детали мастер-криптоключа, pub
означает, что это открытая часть криптоключа. Остальные поля:
- rsa3072
- используемый криптоалгоритм и его параметры, в данном случае это RSA с ключом длиной 3072 бит;
- 2023-07-05
- дата создания ключа;
- [SC]
- здесь указываются Возможности криптоключа (Capabilities, Usage), каждая буква означает свою возможность (их полный список здесь в секции Field 12 - Key capabilities). В нашем случае S означает Sign и C — Certify;
- [expires: 2025-07-04]
- здесь указывается дата окончания, в нашем примере это 25 июля 2025 года, если ключ без даты окончания, этот фрагмент будет отсутствовать.
Деление на колонки весьма условное, но обычно из контекста понятно, где какие данные. В разных версиях формат вывода может меняться, чтобы получить гарантированный машиночитаемый, добавьте аргумент
--with-colons
.
Строка 57F80A6420E2B1CA6F990F04BB9152FD77C92BB6
— это отпечаток (fingerprint) криптоключа, я выше писал, как из отпечатка формируется идентификатор.
Теперь следующий блок:
uid [ultimate] Sergey Stolyarov <[email protected]>
Строка uid
означает, что здесь лежит информация о личности/персоне пользователя (по-английски это обозначается identity), по сути весь текст тут является ID этого пользователя. Пользователь служит для привязки бинарных данных ключа к конкретной персоне. В нашем блоке данных user-ID: Sergey Stolyarov <[email protected]>
.
Следующий блок:
sub rsa3072 2023-07-05 [E] [expires: 2025-07-04]
Тип sub
означает, что здесь находится открытая часть подчинённого криптоключа. Остальные параметры такие же, как в мастер-криптоключе: RSA-ключ 3072 бита, дата создания — 2023-07-05. Подчинённый криптоключ используется (обратите внимание на флаг возможностей ключа [E]
, это Encrypt) для шифрования/дешифрования данных (открытая часть для шифрования, закрытая — для дешифрования).
❈ ❈ ❈
По умолчанию при выводе списка ключей идентификаторы криптоключей не отображаются, это можно исправить, если добавить аргумент --keyid-format long
:
gpg --keyid-format long --list-keys
/home/serge/gnupg-demo/pubring.kbx
------------------------------------------------------
pub rsa3072/BB9152FD77C92BB6 2023-07-05 [SC] [expires: 2025-07-04]
57F80A6420E2B1CA6F990F04BB9152FD77C92BB6
uid [ultimate] Sergei Stolyarov (alternative address) <[email protected]>
uid [ultimate] Sergey Stolyarov <[email protected]>
sub rsa3072/4770F007D9F1AAF7 2023-07-05 [E] [expires: 2025-07-04]
sub rsa2048/E6313E35130E5AF2 2023-07-05 [E] [expires: 2024-07-04]
sub dsa2048/58A80061F8BDCAEC 2023-07-05 [S] [expires: 2024-07-04]
Идентификаторы добавляются после названия используемого криптоалгоритма.
Закрытый ключ¶
Список закрытых ключей смотрим командой --list-secret-keys
$ gpg --list-secret-keys
/home/serge/gnupg-demo/pubring.kbx
------------------------------------------------------
sec rsa3072 2023-07-05 [SC] [expires: 2025-07-04]
57F80A6420E2B1CA6F990F04BB9152FD77C92BB6
uid [ultimate] Sergey Stolyarov <[email protected]>
ssb rsa3072 2023-07-05 [E] [expires: 2025-07-04]
Формат вывода здесь такой же, как и для открытых ключей. Обратите внимание, что ID криптоключей здесь те же самые (если указать аргумент --keyid-format long
), то есть криптоключи закрытой и открытой частей образуют связную пару.
Здесь sec
означает закрытый мастер-криптоключ, он используется для создания подписи данных.
ssb
обозначает блок данных с закрытым подчинённым криптоключом. Этот ключ используется для расшифровывания данных, зашифрованных открытым парным криптоключом из предыдущей секции.
При отображении закрытого ключа дублируются все записи о пользователях/identity.
Cуть мастер-криптоключа — он используется для подписывания данных, но не для шифрования. Эти две вещи связаны напрямую, криптоключ для подписывания не просто так был выбран главным в GnuPG-ключе: все важные блоки данных в открытом ключе подписаны мастер-криптоключом. Это означает, что распространяемый открытый ключ невозможно модифицировать, не сломав подписи блоков. Например, если злоумышленник подменит какой-нибудь e-mail (т.е. uid-блок) в открытом ключе, то он не сможет этот подменный блок подписать так, чтобы он прошёл проверку открытой частью мастер-криптоключа.
Распространение открытого ключа¶
Базовые моменты¶
Принцип функционирования GnuPG описан много где, поэтому без подробностей: храните зашифрованный уникальной парольной фразой закрытый ключ в надёжном месте, раздавайте свой открытый ключ на все доступные сервера открытых ключей (и не забывайте после обновления ключа опять его загружать на сервер).
Клиент обращается к серверу ключей либо за новым ключом (нужно знать его ID), либо за обновлением уже существующего.
Вот как можно запросить открытый ключ (в данном примере мой настоящий ключ):
$ gpg --keyserver keys.gnupg.net --recv-keys 4695E6355B20C7D2
А вот так можно отправить свой открытый ключ на сервер (это я обновляю свой ключ, поэтому указываю его ID):
$ gpg --keyserver keys.gnupg.net --send-keys 4695E6355B20C7D2
Обновить локальные открытые ключи в конфиге можно командой --refresh-keys
, она для каждого ID ключа попытается скачать более новую его версию и обновить записи в конфиге:
$ gpg --refresh-keys --keyserver keys.gnupg.net
Практически все серверы ключей не позволяют удалять блоки данных из ключа. Объяснение этому простое — подписываются только отдельные блоки в ключе, поэтому если удалить блок вместе с его подписью, мы получим валидный (но изменённый злоумышленником) ключ. Поэтому, даже если вы удалите из открытого ключа, например, identity-блок, вы не сможете его удалить с сервера ключей. Неким аналогом удаления блоков является так называемый отзыв, специальный вид цифровой подписи, помечающий блок как более невалидный. Программы обычно такие блоки либо игнорируют как несуществующие, либо выдают специальные предупреждения, если на невалидные блоки завязаны какие-либо действия.
Таким образом, очень внимательно подходите к вопросу выбора имени или добавления подчинённого криптоключа, после публикации открытого ключа «откатить» изменения полностью уже не получится.
Распространение изменений¶
Два стандартных способа распространения открытого ключа: через экспорт с последующим выкладыванием куда-нибудь или через сервер ключей. Про экспорт на сервер я писал выше (команда --send-keys
). А файловый экспорт делается так:
$ gpg --armor -o ~/tmp/57F80A6420E2B1CA6F990F04BB9152FD77C92BB6.pub --export 57F80A6420E2B1CA6F990F04BB9152FD77C92BB6
Если не указывать --armor
, то ключ будет выдан в двоичном формате. Дальше этот файл (57F80A6420E2B1CA6F990F04BB9152FD77C92BB6.pub) можно, например, на сайте выложить вместе с такой инструкцией по импорту:
$ gpg --fetch-keys http://example.com/57F80A6420E2B1CA6F990F04BB9152FD77C92BB6.pub
Эта команда сама скачает и затем импортирует ключ в конфиг.
При любом импорте существует несколько сценариев применения изменений, «тонкая настройка» этого делается через команду --import-options
, впрочем, действия по умолчанию вполне нормальны и особой необходимости влезать в этот процесс нет.
Редактирование ключа¶
Базовые моменты¶
Стандартное редактирование ключа происходит в интерактивном режиме, который запускается командой --edit-key
:
$ gpg --edit-key 57F80A6420E2B1CA6F990F04BB9152FD77C92BB6
gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
sec rsa3072/BB9152FD77C92BB6
created: 2023-07-05 expires: 2025-07-04 usage: SC
trust: ultimate validity: ultimate
ssb rsa3072/4770F007D9F1AAF7
created: 2023-07-05 expires: 2025-07-04 usage: E
[ultimate] (1). Sergey Stolyarov <[email protected]>
gpg>
Также можно вместо ID ключа использовать имя пользователя, вот эквивалентная команда:
$ gpg --edit-key [email protected]
Посмотреть список всех2 доступных команд можно командой help
. В процессе выполнения команд данные в ключ сразу не записываются, получается такая типа транзакционность. Записать изменения (и сразу же выйти) можно командой save
. Выйти без сохранения можно либо через Ctrl+C
, либо командой quit
.
Чаще всего при редактировании ключа по-настоящему меняется только открытая часть: редактируется блок данных (либо добавляется новый) и для него создаётся новая подпись.
Также в интерактивный режим редактирования можно войти через другие команды, например, при подписывании чужого ключа своим.
❈ ❈ ❈
Важный момент
Вы можете редактировать любой ключ, а не только свой собственный. Но при запросе данных с сервера ключей удалённые блоки могут приехать снова.
Редактирование пользователя/identity¶
Наиболее часто используется команда adduid
, она добавляет в ключ новый блок с USER-ID/identity: привязать к ключу новый емейл, например; сама команда крайне простая: вводим данные пользователя, вводим парольную фразу ключа и всё:
gpg> adduid Real name: Sergei Stolyarov Email address: [email protected] Comment: alternative address You selected this USER-ID: "Sergei Stolyarov (alternative address)" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O sec rsa3072/BB9152FD77C92BB6 created: 2023-07-05 expires: 2025-07-04 usage: SC trust: ultimate validity: ultimate ssb rsa3072/4770F007D9F1AAF7 created: 2023-07-05 expires: 2025-07-04 usage: E [ultimate] (1) Sergey Stolyarov [ unknown] (2). Sergei Stolyarov (alternative address) gpg>
Ввод парольной фразы нужен для создания подписи для добавленного пользователя, подпись подтверждает, что пользователь добавлен именно владельцем этого ключа.
Чтобы удалить USER-ID, нужно в режиме редактирование сначала выделить его командой uid N
, где N — номер user-ID из списка пользователей, на листинге выше номера указаны в круглых скобках перед непосредственно ID. После выделения командой deluid
выделенных пользователей можно удалить. Да, выбрать можно сразу несколько пользователей, выбранные в списке отмечаются звёздочкой:
[ultimate] (1) Sergey Stolyarov <[email protected]>
[ unknown] (2)* Sergei Stolyarov (alternative address) <[email protected]>
Первичный (по-английски — primary) обозначается точкой после номера пользователя, в листинге выше это (1).
Сменить первичного пользователя можно так: выделить его (через uid 2
, например) и далее команду primary
:
gpg> uid 2 sec rsa3072/BB9152FD77C92BB6 created: 2023-07-05 expires: 2025-07-04 usage: SC trust: ultimate validity: ultimate ssb rsa3072/4770F007D9F1AAF7 created: 2023-07-05 expires: 2025-07-04 usage: E [ultimate] (1) Sergey Stolyarov[ unknown] (2)* Sergei Stolyarov (alternative address) gpg> primary sec rsa3072/BB9152FD77C92BB6 created: 2023-07-05 expires: 2025-07-04 usage: SC trust: ultimate validity: ultimate ssb rsa3072/4770F007D9F1AAF7 created: 2023-07-05 expires: 2025-07-04 usage: E [ultimate] (1) Sergey Stolyarov [ unknown] (2)* Sergei Stolyarov (alternative address)
Первичный пользователь используется как пользователь по умолчанию при разруливании всяких сложностей (например, коллизий) или при отображении параметров найденного ключа (например, при вводе парольной фразы), если у вас в ключе несколько пользователей.
Командой deluid
можно удалить выделенные блоки с USER-ID, однако смысл в этой команде есть, только если вы ещё не успели поделиться обновлённым открытым ключом с другими или отправть его на сервер ключей.
Командой revuid
можно отозвать выделенные user-ID, отозванные пользователи помечаются специальным образом и во многих случаях это почти то же самое, что удалённый. Необходимость в отзыве возникает, например, если вы потеряли один из емейлов и хотите пометить его в списке, чтобы его другие не использовали.
Редактирование подчинённых криптоключей¶
Блоки криптоключей можно удалять, добавлять и отзывать. Криптоключи бывают двух видов: для подписывания и для шифрования. Создаются они всегда парой: закрытый криптоключ уходит в блок закрытого ключа, а открытый криптоключ — в открытый.
Посмотреть, какие у вас криптоключи, можно командой gpg --list-keys
, это те самые [SC]
, [E]
из колонки Возможности. Альтернативно можно посмотреть в команде list
режима редактирования:
sec rsa3072/BB9152FD77C92BB6
created: 2023-07-05 expires: 2025-07-04 usage: SC
trust: ultimate validity: ultimate
ssb rsa3072/4770F007D9F1AAF7
created: 2023-07-05 expires: 2025-07-04 usage: E
[ultimate] (1) Sergey Stolyarov <[email protected]>
[ unknown] (2)* Sergei Stolyarov (alternative address) <[email protected]>
В списке видно один подчинённый криптоключ, его ID — 4770F007D9F1AAF7
. В конце строки можно видеть, как этот криптоключ можно использовать: usage: S
означает signing, то есть этим криптоключом можно подписывать сообщения, а usage: E
означает encryption, то есть криптоключом можно шифровать данные. Запись usage: SC
означает, что ключ можно использовать для подписывания (Signing), удостоверения (Certify, потом расскажу, что это такое). Есть ещё также буква A
, которая означает authentication, но на практике это почти не используется (чуть подробнее здесь можно прочитать).
Любой подчинённый криптоключ можно удалить или отозвать.
Создать новый подчинённый криптоключ можно в интерактивном режиме. Например, создадим новый ключ для шифрования данных (RSA 2048 bit, срок жизни 1 год):
gpg> addkey Please select what kind of key you want: (3) DSA (sign only) (4) RSA (sign only) (5) Elgamal (encrypt only) (6) RSA (encrypt only) (14) Existing key from card Your selection? 6 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (3072) 2048 Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire= key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 1y Key expires at четверг, 4 июля 2024 г. 18:58:36 +07 Is this correct? (y/N) y Really create? (y/N) y We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. sec rsa3072/BB9152FD77C92BB6 created: 2023-07-05 expires: 2025-07-04 usage: SC trust: ultimate validity: ultimate ssb rsa3072/4770F007D9F1AAF7 created: 2023-07-05 expires: 2025-07-04 usage: E ssb rsa2048/E6313E35130E5AF2 created: 2023-07-05 expires: 2024-07-04 usage: E [ultimate] (1). Sergei Stolyarov (alternative address) [ultimate] (2) Sergey Stolyarov gpg> save
После создания новый криптоключ можно использовать для шифрования или подписывания вместо мастер-криптоключа. Рассмотрим такую конфигурацию:
sec rsa3072/BB9152FD77C92BB6
created: 2023-07-05 expires: 2025-07-04 usage: SC
trust: ultimate validity: ultimate
ssb rsa3072/4770F007D9F1AAF7
created: 2023-07-05 expires: 2025-07-04 usage: E
ssb rsa2048/E6313E35130E5AF2
created: 2023-07-05 expires: 2024-07-04 usage: E
ssb dsa2048/58A80061F8BDCAEC
created: 2023-07-05 expires: 2024-07-04 usage: S
[ultimate] (1). Sergei Stolyarov (alternative address) <[email protected]>
[ultimate] (2) Sergey Stolyarov <[email protected]>
Здесь у нас:
- мастер-криптоключ с ID BB9152FD77C92BB6 — этим криптоключом можно создавать электронные подписи (буква
S
) и удостоверять/сертифицировать (букваC
); - RSA-криптоключ с ID 4770F007D9F1AAF7 — для шифрования (буква
E
); - RSA-криптоключ с ID E6313E35130E5AF2 — для шифрования;
- DSA-криптоключ с ID 58A80061F8BDCAEC — для подписывания.
Допустим, какой-то человек получил этот открытый ключ и хочет зашифровать им файл GPL.txt
, для этого он использует вот такую команду (результат по умолчанию записывается в GPL.txt.gpg
):
$ gpg --recipient [email protected] --encrypt GPL.txt
Каким именно криптоключом будет зашифрован файл? У нас в ключе их два: один с ID 4770F007D9F1AAF7 и второй с ID E6313E35130E5AF2. По умолчанию будет использоваться самый последний из созданных ключей, в нашем случае это подчинённый ключ с ID E6313E35130E5AF2.
Однако можно указать gpg, какой конкретно криптоключ использовать для шифрования (обратите внимание на восклицательный знак после ID подчинённого криптоключа):
$ gpg --recipient 4770F007D9F1AAF7! --encrypt GPL.txt
Восклицательный знак после ID криптоключа заставляет gpg использовать именно этот криптоключ и запрещает обычную процедуру его поиска. Точно такой же метод можно использовать для подписывания данных. Посмотрите на разницу между вот этими двумя командами, отличающимися только лишь одним восклицательным знаком:
$ gpg -o GPL.signed -u BB9152FD77C92BB6 -s GPL.txt
$ gpg --list-packets GPL.signed
...
:signature packet: algo 17, keyid 58A80061F8BDCAEC
version 4, created 1688558972, md5len 0, sigclass 0x00
digest algo 8, begin of digest 57 22
hashed subpkt 33 len 21 (issuer fpr v4 9DB600D2D7C245EBA1CF3A4958A80061F8BDCAEC)
hashed subpkt 2 len 4 (sig created 2023-07-05)
subpkt 16 len 8 (issuer key ID 58A80061F8BDCAEC)
data: [254 bits]
data: [256 bits]
...
сравните с:
$ gpg -o GPL.signed -u BB9152FD77C92BB6! -s GPL.txt
$ gpg --list-packets GPL.signed
...
:signature packet: algo 1, keyid BB9152FD77C92BB6
version 4, created 1688559054, md5len 0, sigclass 0x00
digest algo 8, begin of digest 53 84
hashed subpkt 33 len 21 (issuer fpr v4 57F80A6420E2B1CA6F990F04BB9152FD77C92BB6)
hashed subpkt 2 len 4 (sig created 2023-07-05)
subpkt 16 len 8 (issuer key ID BB9152FD77C92BB6)
data: [3066 bits]
...
В обоих случаях в качестве пользователя передан ID мастер-криптоключа, однако в первом случае gpg вместо него выбирает ключ автоматически (с ID 58A80061F8BDCAEC). А вот если указать восклицательный знак, то будет использован в точности указанный криптоключ, в данном случае — мастер-криптоключ.
С подписыванием ровно то же самое: непонятно как выбирается ключ для подписи, явно ключ можно указать, добавляя восклицательный знак после ID криптоключа.
Здесь мы использовали команду
gpg --list-packets
, которая позволяет смотреть структуру OpenPGP-данных.
Подписывание чужого ключа¶
Одной из главных декларируемых фич OpenPGP является сеть доверия (web of trust), что это такое, можете почитать в википедии (только на английском). В основе сети доверия лежит подписывание ключей, суть его в следующем: если вы доверяете человеку, у вас есть его открытый ключ и вы абсолютно точно уверены, что это именно его открытый ключ, то вы можете подписать его открытый ключ своим закрытым ключом. Такой процедурой вы подтверждаете, что этот ключ действительно принадлежит его владельцу. Чем больше таких авторитетных подписей, тем достовернее и надёжнее ключ (таков ритуал).
Технически всё несколько сложнее, на самом деле вы подписываете/удостоверяете не открытый ключ, а связку пользователь/identity плюс открытый ключ. Везде принято говорить «подписывание ключа», хотя на самом деле вы своей электронной подписью удостоверяете/подтверждаете, что данный UID принадлежит данному открытому ключу.
Для просмотра подписей блоков данных ключа есть команда --list-sigs
, она работает как команда --list-keys
, только для каждого identity-блока показывает созданные для него подписи:
$ gpg --list-sigs
/home/serge/gnupg-demo/pubring.kbx
----------------------------------------------------
pub rsa3072 2023-07-05 [SC] [expires: 2025-07-04]
57F80A6420E2B1CA6F990F04BB9152FD77C92BB6
uid [ultimate] Sergei Stolyarov (alternative address) <[email protected]>
sig 3 BB9152FD77C92BB6 2023-07-05 Sergei Stolyarov (alternative address) <[email protected]>
uid [ultimate] Sergey Stolyarov <[email protected]>
sig 3 BB9152FD77C92BB6 2023-07-05 Sergei Stolyarov (alternative address) <[email protected]>
sub rsa3072 2023-07-05 [E] [expires: 2025-07-04]
sig BB9152FD77C92BB6 2023-07-05 Sergei Stolyarov (alternative address) <[email protected]>
sub rsa2048 2023-07-05 [E] [expires: 2024-07-04]
sig BB9152FD77C92BB6 2023-07-05 Sergei Stolyarov (alternative address) <[email protected]>
sub dsa2048 2023-07-05 [S] [expires: 2024-07-04]
sig BB9152FD77C92BB6 2023-07-05 Sergei Stolyarov (alternative address) <[email protected]>
Структура листинга аналогична команде --list-keys
, только теперь мы видим дополнительные строки — они начинаются со слова sig
— это подписи (иногда ещё говорят сигнатуры) для соответствующих блоков. Сразу после создания ключевой пары, у каждого блока в ключе есть только одна подпись, она создана мастер-криптоключом (напомню, что это сделано для того, чтобы можно было безопасно таскать кучку блоков вместе, а целостность (что никто не подменил блок) как раз обеспечивается подписью мастер-криптоключа).
❈ ❈ ❈
Процесс подписывания блоков очень запутанный и нелогичный, поскольку у подписей бывают различные атрибуты (например, уровень доверия), а выставляются они сложным и нелогичным образом. Ниже я рассмотрю несколько типовых и не очень сценариев.
В некоторых сценариях я буду работать с моим собственным открытым ключом с идентификатором 4695E6355B20C7D2, его мы получили в одном из примеров выше. Также я буду пользоваться тестовым ключом (UID: [email protected]), который вы можете установить такой командой:
curl https://raw.githubusercontent.com/sigsergv/blog-data/master/gnupg-explained/jsmith.pub | gpg --import
Простое подписывание ключа¶
Сценарий: вы получили публичный ключ другого человека ([email protected]), сохранили в конфигурации и хотите подписать (удостоверить) его своим ключом. Типичная команда для этого сценария выглядит так:
% gpg --sign-key [email protected] pub rsa3072/8B9E67786ED5FF00 created: 2023-07-06 expires: 2025-07-05 usage: SC trust: unknown validity: unknown sub rsa3072/F087C814738F7CC3 created: 2023-07-06 expires: 2025-07-05 usage: E [ unknown] (1). John Smithpub rsa3072/8B9E67786ED5FF00 created: 2023-07-06 expires: 2025-07-05 usage: SC trust: unknown validity: unknown Primary key fingerprint: 7085 056E 4099 C4A6 2CA3 1951 8B9E 6778 6ED5 FF00 John Smith This key is due to expire on 2025-07-05. Are you sure that you want to sign this key with your key "Sergei Stolyarov (alternative address) " (BB9152FD77C92BB6) Really sign? (y/N) y
То есть мы указываем ID/e-mail/имя/часть имени, вводим парольную фразу от нашего закрытого ключа и получаем новую подпись в ключе для [email protected]:
$ gpg --list-sigs [email protected] gpg: checking the trustdb gpg: marginals needed: 3 completes needed: 1 trust model: pgp gpg: depth: 0 valid: 1 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 1u gpg: depth: 1 valid: 1 signed: 0 trust: 1-, 0q, 0n, 0m, 0f, 0u gpg: next trustdb check due at 2025-07-04 pub rsa3072 2023-07-06 [SC] [expires: 2025-07-05] 7085056E4099C4A62CA319518B9E67786ED5FF00 uid [ full ] John Smithsig 3 8B9E67786ED5FF00 2023-07-06 John Smith sig BB9152FD77C92BB6 2023-07-06 Sergei Stolyarov (alternative address) sub rsa3072 2023-07-06 [E] [expires: 2025-07-05] sig 8B9E67786ED5FF00 2023-07-06 John Smith
Формат вывода при отображении подписей¶
Структуру строк-подписей рассмотрим на примере этой (это подпись блока для пользователя):
uid [ultimate] Sergey Stolyarov <[email protected]>
sig 3 BB9152FD77C92BB6 2023-07-05 Sergei Stolyarov (alternative address) <[email protected]>
После слова-маркера sig
идёт набор из семи флагов подписи, затем ID криптоключа, которым сделана подпись, далее дата создания подписи, а в конце ID пользователя (тут как раз и показывается первичный uid, о котором шла речь чуть выше). Если для данного ID криптоключа в конфиге нет открытого ключа, то вместо строки с информацией о пользователе показывается нечто вроде [User ID not found]
.
Теперь о флагах, для каждого типа флага отведена одна позиция в списке флагов.
sig 3 BB9152FD77C92BB6 2023-07-05 Sergei Stolyarov (alternative address) <[email protected]>
^^^^^^^
│││││││
││││││└─ [7] уровень доверия к ключу
│││││└── [6] `X`, просроченная подпись
││││└─── [5] `N`, в подписи есть Notation
│││└──── [4] `P`, в подписи указан Policy URL
││└───── [3] `R`, неотзываемая подпись
│└────── [2] `L`, неэкспортируемая подпись
└─────── [1] (0, 1, 2 или 3) уровень проверки
Флаг [1] уровень проверки может содержать 0, 1, 2 или 3, по умолчанию стоит 0. Каждый уровень означает следующее:
0 — нет никакого особого уровня проверки, это значение по умолчанию, вы не думая подписали этот блок.
1 — это означает, что вы считаете, что ключ принадлежит указанной персоне, но никак это не проверяли.
2 — это означает, что вы предприняли самые минимальные усилия, чтобы удостовериться, что ключ принадлежит указанной персоне.
3 — это означает, что вы прям совсем точно знаете, что ключ принадлежит кому надо.
Для своих собственных пользователей ключа, как вы можете видеть из листинга выше, стоит уровень проверки 3, что в принципе логично. Если вы просто создаёте подпись без указания конкретного уровня, то подразумевается уровень 0.
Флаг [2] L
показывается, если подпись была создана локальной (неэкспортируемой), локальная подпись не выгружается на ключевые сервера и доступна только для локального использования.
Флаг [3] R
показывается, если подпись была помечена как неотзываемая.
Флаг [4] P
показывается, если в подписи указан адрес политики подписи, посмотреть список этих адресов можно командой gpg --list-options show-policy-urls --list-sigs
.
Флаг [5] N
показывается, если в подписи было указано поле Notation, их можно посмотреть комадной gpg --list-options show-notations --list-sigs
.
Флаг [6] X
показывается, если срок жизни подписи истёк.
Флаг [7] показывает уровень доверия подписи, здесь может быть число от 1 до 9 или буква T, если уровень доверия больше 10.
Простое подписывание ключа с множественными identity¶
Когда в ключе есть несколько identity, процесс подписи усложняется, поскольку подпись генерируется отдельно для каждой identity-записи и необходимо определиться, доверяем ли мы каждой записи или только некоторым.
Для демонстрации я использую ключ, который можно импортировать такой командой:
curl https://raw.githubusercontent.com/sigsergv/blog-data/master/gnupg-explained/jsmith-multiple.pub | gpg --import
В этом ключе две USER-ID записи, поэтому команда gpg --sign-key [email protected]
будет работать по несколько более сложному сценарию:
$ gpg --sign-key [email protected] pub rsa3072/8B9E67786ED5FF00 created: 2023-07-06 expires: 2025-07-05 usage: SC trust: unknown validity: unknown sub rsa3072/F087C814738F7CC3 created: 2023-07-06 expires: 2025-07-05 usage: E [ unknown] (1). John Smith[ unknown] (2) John Smith (work) Really sign all user IDs? (y/N) n Hint: Select the user IDs to sign gpg> uid 2 pub rsa3072/8B9E67786ED5FF00 created: 2023-07-06 expires: 2025-07-05 usage: SC trust: unknown validity: unknown sub rsa3072/F087C814738F7CC3 created: 2023-07-06 expires: 2025-07-05 usage: E [ unknown] (1). John Smith [ unknown] (2)* John Smith (work) gpg> sign pub rsa3072/8B9E67786ED5FF00 created: 2023-07-06 expires: 2025-07-05 usage: SC trust: unknown validity: unknown Primary key fingerprint: 7085 056E 4099 C4A6 2CA3 1951 8B9E 6778 6ED5 FF00 John Smith (work) This key is due to expire on 2025-07-05. Are you sure that you want to sign this key with your key "Sergei Stolyarov (alternative address) " (BB9152FD77C92BB6) Really sign? (y/N) y .... gpg> save
Так как мы хотим подписать только один USER-ID, то мы отказываемся от подписывания всех:
Really sign all user IDs? (y/N) n
И дальше выбираем конкретную запись USER-ID и вводим команду для подписи
gpg> uid 2
gpg> sign
Проверяем, что получилось.
% gpg --list-sigs 7085056E4099C4A62CA319518B9E67786ED5FF00 ... pub rsa3072 2023-07-06 [SC] [expires: 2025-07-05] 7085056E4099C4A62CA319518B9E67786ED5FF00 uid [ unknown] John Smithsig 3 8B9E67786ED5FF00 2023-07-06 John Smith uid [ full ] John Smith (work) sig 3 8B9E67786ED5FF00 2023-07-06 John Smith sig BB9152FD77C92BB6 2023-07-07 Sergei Stolyarov (alternative address) sub rsa3072 2023-07-06 [E] [expires: 2025-07-05] sig 8B9E67786ED5FF00 2023-07-06 John Smith
Подписывание ключей с дополнительными параметрами¶
Аргумент --sign-key
или команда sign
в интерактивном режиме подписывает ключ в режиме по умолчанию, создавая обычную подпись. Однако можно создавать и другие типы подписей: локальную, неотзываемую, с декларированным доверием.
Отправка созданных подписей на сервер ключей¶
Некоторые добавленные локально подписи можно отправить на сервер ключей. Делается это такой командой:
$ gpg --keyserver keys.gnupg.net --send-keys 4695E6355B20C7D2
В результате на сервер keys.gnupg.net уедет созданная вами подпись на пользователя/identity.
Управление ключами¶
При активном использовании ваш собственный ключ и внешние ключи постоянно меняются:
- добавляются новые подчинённые ключи;
- меняются даты окончания ключей;
- добавляются новые identity;
- отзываются (revoke) блоки данных;
- добавляются подписи от других людей.
OpenPGP не навязывает конкретных сценариев управления ключами, однако есть рекомендуемые сообществом подходы и рекомендации. Они вам пригодятся, если вы пользуетесь gnupg в активном сообществе.
- Выполняйте периодические обновления существующих ключей с серверов ключей.
- Будьте осторожны с импортом ключей, включая загрузку с серверов ключей. Всегда проверяйте отпечаток (fingerprint) через второй или третий каналы (например, личным звонком или встречей).
- Для собственных ключей всегда выставляйте дату окончания не более двух лет. При необходимости дату окончания можно продлевать.
- Создайте и сохраните в безопасном месте сертификат отзыва ключа.
- Мастер-криптоключ используйте только для сертификации ключей, identity и других блоков OpenPGP-ключей.
- Для подписывания внешних данных или шифрования используйте только подчинённые ключи.
Защита данных¶
Шифрование данных¶
Криптоключ можно использовать для шифрования и дешифрования данных, если он предоставляет такую возможность. Поскольку в ключе хранятся криптоключи асимметричных криптосистем, для шифрования используется открытый криптоключ, а для дешифрования — закрытый. В стандартной конфигурации мастер-криптоключ используется для подписывания, а подчинённый (если он есть) — для шифрования.
Типичная схема здесь: в вашем конфиге есть ключ получателя, вы шифруете файл открытым ключом получателя и отправляете зашифрованные данные, получатель своим закрытым ключом их расшифровывает и получает исходный файл. Однако здесь есть большая проблема — поскольку открытый ключ публичный, злоумышленник может подменить файл, просто зашифровав свои данные этим же общедоступным ключом. Проблема решается через аутентифицированное шифрование (authenticated encryption), когда данные дополнительно подписываются закрытым ключом отправителя.
Вот как выглядит корректное шифрование файла GPL.txt:
$ gpg --encrypt --sign -r [email protected] GPL.txt gpg: 33C9C3B691AB7DC8: There is no assurance this key belongs to the named user sub rsa4096/33C9C3B691AB7DC8 2012-04-18 Sergey StolyarovPrimary key fingerprint: 87E2 946B 041B CF31 8C4D 5BA7 4695 E635 5B20 C7D2 Subkey fingerprint: 5306 F3FF D40A F9A5 E451 09C3 33C9 C3B6 91AB 7DC8 It is NOT certain that the key belongs to the person named in the user ID. If you *really* know what you are doing, you may answer the next question with yes. Use this key anyway? (y/N) y
Мы видим стандартное предупреждение, доверяем ли мы этому ключу, соглашаемся, получаем дополнительный вопрос о подписывании, вводим парольную фразу, получаем зашифрованный и подписанный файл GPL.txt.gpg
. Обратите внимание, что если не указать аргумент --sign
, то передаваемые данные не будут подписаны.
Естественно, получатель должен в своём конфиге иметь ваш OpenPGP-ключ, чтобы аутентифицировать подпись.
Технически аутентифицированное шифрование реализовано в виде схемы: сначала подписываем данные, упаковываем подпись и исходные данные в один блок и дальше шифруем уже его. В результате, если у вас нет закрытого ключа для расшифровки, вы никак не сможете определить, находятся ли внутри OpenPGP-сообщения подписанные или неподписанные данные.
Дешифрование данных¶
Если вы получили зашифрованный файл GPL.txt.gpg
, то расшифровать его (и записать результат в file.txt
) можно такой командой:
$ gpg -o file.txt -d GPL.txt.gpg
Если в файле дополнительно присутствует подпись, вы получите сообщение об этом плюс сообщение, удалось ли верифицировать эту подпись.
Что осталось за рамками статьи¶
Самый главный компонент gnupg-инфраструктуры, о котором я не рассказывал — это GnuPG Agent, это специальная программа для безопасного управления закрытыми ключами. Обычно он работает совершенно прозрачно и вы его присутствие даже не замечаете. Рассказ о нём — это тема отдельной статьи.
Также я не рассказывал детально о принятых в разных сообществах практиках использования OpenPGP (например, в электронной почте или при организации общения сообщества Debian-разработчиков).
Полезное дополнительное чтиво¶
- http://blog.dest-unreach.be/2009/04/13/the-internals-of-a-gpgpgp-key
- http://www.phildev.net/pgp/gpgsigning.html — параноидальное описание параноидальной подписи.
- http://wiki.openskills.org/OpenSkills/GPG+User+ID+maintenance
- https://wiki.debian.org/Subkeys
- https://davesteele.github.io/gpg/2014/09/20/anatomy-of-a-gpg-key/
-
Вообще, команда
--list-keys
печатает не все блоки для каждого ключа, например, она не выводит подписи, но для общего понимания структуры ключа это не особо важно. ↩ -
На самом деле не всех, часть доступных команд в этом списке отсутствует, видимо, они считаются слишком продвинутыми. Пример такой команды —
cross-certify
, про неё можно тут почитать. ↩
Спасибо, отличная статья. Может подскажете, как одной командой получить отметку primary uid ключа/ключей? Т.к. количество этих самых uid может быть больше одного и, по моим наблюдениям, primary uid не всегда выводится первым. Явно такой uid отмечается только в режиме редактирования ключа. Особенно интересно в контексте опции --with-colons
Хороший вопрос! В параметрах --list-keys я не нашёл такого, при использовании --with-colons вроде бы primary uid помечается большими буквами в 12 поле:
Тут речь про ключ, как я понял. А меня интересует uid, у которого я насчитал всего 11 полей. А еще в документации для первого поля упоминается такое:
Эх, жаль.