Serghei Iakovlev
My notebook, workshop, a place where I share my experiences and thoughts

Шпаргалка по основным командам GnuPG

Вероятно я не очень интенсивно использую GnuPG. По этому, когда мне нужно прибегнуть к его инструментам, я начинаю искать по закладкам, заметкам, истории, пытаясь вспомнить как я это делал в прошлый раз. Это послужило некоторой мотивацией для меня, создать эту шпаргалку по основным командам GnuPG. При написании шпаргалки я решил добавить в неё не только то, что часто вспоминаю сам, но и более общую информацию, сделав её таким образом полезной не только для меня. Надеюсь у меня это получилось. Если вы заметили неточность или хотели бы, чтобы я добавил что-то интересное, напишите в комментариях или лично мне.

Данная шпаргалка не претендует на полноту и вероятно содержит неточности связанные с используемой версией или операционной системой. Некоторые вещи скорее всего не будут работать в Windows. Для работы с GnuPG я использую терминал, кроме того, я использую версию 2.x. За более подробной и развернутой информацией по GnuPG обращайтесь к документации.

Базовые команды

Создание ключа

$ gpg --gen-key

Данная команда запускает сокращенную версию диалога генерации ключа. Ответив на несколько простых вопросов и придумав пароль, мы получим новый ключ. По окончанию диалога на экран будет выведена информация о новом ключе:

pub   rsa3072/0x301033506DB51CB6 2021-04-14 [SC] [expires: 2023-04-14]
      Key fingerprint = 8DEC 70A8 1BB2 0802 EA7F  E9F7 3010 3350 6DB5 1CB6
uid                              John <john@doe.com>
sub   rsa3072/0x048D9BCAC76ABA82 2021-04-14 [E] [expires: 2023-04-14]

В вашем конкретном случае вывод будет другой и вероятно в другом формате. Формат вывода я настраивал отдельно, на работу инструмента это не влияет, так что не заостряйте пока на этом внимание. Для более развернутого диалога можно использовать команду gpg --full-generate-key.

Экспорт публичного ключа

Используйте команду --export для того, чтобы экспортировать свой публичный ключ:

# Работает любой из этих вариантов
$ gpg --export --armor john@doe.com
$ gpg --export --armor John
$ gpg --export --armor 301033506DB51CB6

Здесь и далее в качестве идентификатора пользователя может выступать либо его email, либо его имя, либо его ключ. Крайне желательно для подобных задач привыкнуть использовать что-то более уникальное, чем просто имя пользователя. В примере выше имя John не является уникальным и его использование может привести к не совсем очевидному результату. К примеру, если у вас есть 2 пользователя с именем John, экспорт ключа по имени пользователя приведет к слиянию ключей в один, что чаще всего не то, что ожидается. Опция --armor нужна для того, чтобы вывести результат в radix-64 представлении (Base64 + CRC) или говоря по простому — в ASCII кодировке. А по умолчанию ключ выводится в двоичном виде. Везде, где эта опция применима, одна означает одно и то же.

Экспорт приватного ключа

Экспорт приватного ключа работает по аналогии с экспортом публичного, за тем лишь исключением, что вместо --export, мы используем --export-secret-key:

$ gpg --export-secret-key -a john@doe.com

Кроме того, при экспорте приватно ключа у вас потребуют пароль, который вы придумали при создании ключа.

Импорт публичного ключа

$ gpg --import 301033506DB51CB6.asc

Эта команда добавит публичный ключ в вашу связку ключей, если его еще там нет. В примере выше, публичный ключ находится в файле 301033506DB51CB6.asc. Изначально, при экспорте публичного ключа, было выбрано расширение файла asc, чтобы подчеркнуть ASCII природу содержимого файла. Вы можете хранить ключи в файлах с любым расширением, хоть exe, GPG на них не смотрит.

Импорт приватного ключа

Импорт приватного ключа по своей сути мало чем отличается от импорта публично ключа:

$ gpg --import 301033506DB51CB6.key

Здесь у файла с приватным ключом расширение key, которое также может быть произвольным. При импорте ключа у вас потребуют пароль, который вы придумали при создании ключа. При успешном импорте вывод в терминале может быть похож на следующий:

$ gpg --import /mnt/backup/301033506DB51CB6.key
gpg: key 0x301033506DB51CB6: "John <john@doe.com>" imported
gpg: key 0x301033506DB51CB6: secret key imported
gpg: Total number processed: 1
gpg:              unchanged: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1

Если повторить эту же операцию с этим же приватным ключём, то первая строка буде заканчиваться словами "not changed" вместо "imported". В остальном вывод будет идентичным.

Удаление публичного ключа

Удаление производится командой --delete-keys с указанием ключа (в более древних версиях GnuPG — --delete-key). Тут есть подводный камень. Заключается он в том, что если у вас импортирован приватный ключ, то удаление публичного завершится неудачей с соответствующим сообщением:

$ gpg --delete-keys 301033506DB51CB6
gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: there is a secret key for public key "0x301033506DB51CB6"!
gpg: use option "--delete-secret-keys" to delete it first.

Удаление приватного ключа

Приватный ключ удаляется аналогично публичному с тем лишь отличием, что вместо команды --delete-keys используется --delete-secret-keys (в более древних версиях GnuPG — --delete-secret-key).

Вывод списка публичных ключей

Список публичных ключей можно получить командами --list-keys, --list-public-keys либо коротким аналогом -k. В простейшем виде команда выводит в человекочитаемом формате все ваши ключи:

$ gpg --list-public-keys
/home/alice/.gnupg/pubring.kbx
-------------------------------
pub   rsa3072/0x301033506DB51CB6 2021-04-14 [SC] [expires: 2023-04-14]
      Key fingerprint = 8DEC 70A8 1BB2 0802 EA7F  E9F7 3010 3350 6DB5 1CB6
uid                   [ unknown] John <john@doe.com>
sub   rsa3072/0x048D9BCAC76ABA82 2021-04-14 [E] [expires: 2023-04-14]

Формат вывода настраивается отдельно, у вас он может отличаться. Для вывода в машиночитаемом виде используйте --with-colons. Кроме того, возможно указать конкретный ключ, например, чтобы получить по нему подробную информацию:

$ gpg --list-public-keys --with-colons 301033506DB51CB6
tru::1:1618398144:1619029558:3:1:5
pub:-:3072:1:301033506DB51CB6:1618394485:1681466485::-:::scESC::::::23::0:
fpr:::::::::8DEC70A81BB20802EA7FE9F7301033506DB51CB6:
uid:-::::1618394485::CAE426D0577354D87D52A0EB2242E27AC86BAD0C::John <john@doe.com>::::::::::0:
sub:-:3072:1:048D9BCAC76ABA82:1618394485:1681466485:::::e::::::23:
fpr:::::::::D17B499C744AE2602C4EB513048D9BCAC76ABA82:

Вывод списка приватных ключей

Вывод списка приватных ключей с выводом публичных, за тем лишь исключением, что вместо --list-keys, мы используем --list-secret-keys или -K. И да, все те же самые дополнительные опции применимы и здесь:

$ gpg --list-secret-keys 301033506DB51CB6
sec   rsa3072/0x301033506DB51CB6 2021-04-14 [SC] [expires: 2023-04-14]
      Key fingerprint = 8DEC 70A8 1BB2 0802 EA7F  E9F7 3010 3350 6DB5 1CB6
uid                   [ unknown] John <john@doe.com>
ssb   rsa3072/0x048D9BCAC76ABA82 2021-04-14 [E] [expires: 2023-04-14]

Вообще, любые команды по работе с секретными ключами сложнее, длиннее или требуют дополнительных нажатий клавиш (сравните -k и -K).

Вывод отпечатков ключей

Отпечатки ключа проверяются его владельцем. Это может быть сделано при личной встрече, по телефону, или любым другим способом, гарантирующим, что вы общаетесь с владельцем ключа. Если отпечатки полученные вами совпадают с указанными владельцем ключа, то можете быть уверены, что обладаете достоверной копией ключа.

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

Отпечаток любого ключа можно быстро просмотреть командой --fingerprint:

$ gpg --fingerprint 301033506DB51CB6
pub   rsa3072/0x301033506DB51CB6 2021-04-14 [SC] [expires: 2023-04-14]
      Key fingerprint = 8DEC 70A8 1BB2 0802 EA7F  E9F7 3010 3350 6DB5 1CB6
uid                   [ unknown] John <john@doe.com>
sub   rsa3072/0x048D9BCAC76ABA82 2021-04-14 [E] [expires: 2023-04-14]
      Key fingerprint = D17B 499C 744A E260 2C4E  B513 048D 9BCA C76A BA82

Если не указать ключ, будет выведена информация по всем ключам.

Продвинутое использование

Под этим заголовком я собрал команды, которые либо реже используются, либо требуют более глубокого понимания основ работы GnuPG.

Обновление ключей с истекающим сроком действия

Хорошей практикой является создание ключей с ограниченным сроком действия. И если вы ей следуете, то рано или поздно вам понадобится обновить срок действия ваших ключей. В противном случае ключи превратятся в тыкву. Ниже я приведу последовательность действий по обновлению своего ключа.

Для начала, давайте посмотрим на то, какие ключи есть в нашем распоряжении и какой у них срок действия:

$ gpg -k
/Users/egrep/.gnupg/pubring.kbx
-------------------------------
pub   rsa4096/0x1E0B5331219BEA88 2019-05-13 [C] [expires: 2021-04-21]
      Key fingerprint = EDAC 8D91 F82C 0BBD 261C  1329 1E0B 5331 219B EA88
uid                   [ultimate] Serghei Iakovlev <egrep@protonmail.ch>
uid                   [ultimate] Serghei Iakovlev <sadhooklay@gmail.com>
uid                   [ultimate] Serghei Iakovlev <mail@serghei.blog>
sub   rsa4096/0xDFA77DA0F7C016F2 2019-05-13 [E] [expires: 2021-04-21]
sub   rsa4096/0xC6AF1016BBDEA800 2019-05-13 [S] [expires: 2021-04-21]
sub   rsa4096/0x4C8A6A49D31C9CA1 2019-05-13 [A] [expires: 2021-04-21]

Как я писал уже выше, команда -k предназначена для вывода списка всех публичных ключей. В вашем конкретном случае вывод будет отличаться. Я пишу эту статью 17-го апреля 2021 года. Соответственно, мой ключ 1E0B5331219BEA88, а также все подключи будут действительны ещё чуть менее чем четверо суток (до 2021-04-21).

Теперь, видя ключ, срок действия которого необходимо продлить, мне нужно его изменить. Давайте войдем в режим редактирования ключа командой --edit-key:

$ gpg --edit-key 1E0B5331219BEA88
gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret subkeys are available.

pub  rsa4096/0x1E0B5331219BEA88
     created: 2019-05-13  expires: 2021-04-21  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/0xDFA77DA0F7C016F2
     created: 2019-05-13  expires: 2021-04-21  usage: E
ssb  rsa4096/0xC6AF1016BBDEA800
     created: 2019-05-13  expires: 2021-04-21  usage: S
ssb  rsa4096/0x4C8A6A49D31C9CA1
     created: 2019-05-13  expires: 2021-04-21  usage: A
[ultimate] (1). Serghei Iakovlev <egrep@protonmail.ch>
[ultimate] (2)  Serghei Iakovlev <sadhooklay@gmail.com>
[ultimate] (3)  Serghei Iakovlev <mail@serghei.blog>
[ revoked] (4)  Serghei Iakovlev <serghei@phalcon.io>

gpg>

В моём случае на экране появится описание моего ключа, перечень всех подключей и приглашение к вводу (gpg>). Если я хочу изменить ключ, мне необходимо его выбрать командой key с указанием ключа или его индекса (индексы начинаются с нуля). Давайте так и поступим, обновим третий подключ. Выбираем ключ, а затем вызываем команду expire, которая предназначена для продления срока ключа:

gpg> key 4C8A6A49D31C9CA1

pub  rsa4096/0x1E0B5331219BEA88
     created: 2019-05-13  expires: 2021-04-21  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/0xDFA77DA0F7C016F2
     created: 2019-05-13  expires: 2021-04-21  usage: E
ssb  rsa4096/0xC6AF1016BBDEA800
     created: 2019-05-13  expires: 2021-04-21  usage: S
ssb* rsa4096/0x4C8A6A49D31C9CA1
     created: 2019-05-13  expires: 2021-04-21  usage: A
[ultimate] (1). Serghei Iakovlev <egrep@protonmail.ch>
[ultimate] (2)  Serghei Iakovlev <sadhooklay@gmail.com>
[ultimate] (3)  Serghei Iakovlev <mail@serghei.blog>
[ revoked] (4)  Serghei Iakovlev <serghei@phalcon.io>

gpg> expire

После того, как мы нажмем ввод, у нас поинтересуются относительно нового срока. Я укажу 399 дней, а затем, перепроверив новую дату подтвержу свой выбор:

gpg> expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 369
Key expires at Thu Apr 21 15:15:02 2022 EEST
Is this correct? (y/N) y

После нажатия ввода на экране появится все тот же список, но у одного ключа будет обновлена дата. Обратите внимание на последний ключ с обновленной датой (2022-04-21):

sec  rsa4096/0x1E0B5331219BEA88
     created: 2019-05-13  expires: 2021-04-21  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/0xDFA77DA0F7C016F2
     created: 2019-05-13  expires: 2021-04-21  usage: E
ssb  rsa4096/0xC6AF1016BBDEA800
     created: 2019-05-13  expires: 2021-04-21  usage: S
ssb* rsa4096/0x4C8A6A49D31C9CA1
     created: 2019-05-13  expires: 2022-04-21  usage: A
[ultimate] (1). Serghei Iakovlev <egrep@protonmail.ch>
[ultimate] (2)  Serghei Iakovlev <sadhooklay@gmail.com>
[ultimate] (3)  Serghei Iakovlev <mail@serghei.blog>
[ revoked] (4)  Serghei Iakovlev <serghei@phalcon.io>

Похожим образом поступим со вторым и первым подключём. Для изменения основого мастер-ключа я буду использовать команду key 0. После обновления срока действия всех необходимых ключей, их список будет выглядеть следующим образом:

sec  rsa4096/0x1E0B5331219BEA88
     created: 2019-05-13  expires: 2022-04-21  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/0xDFA77DA0F7C016F2
     created: 2019-05-13  expires: 2022-04-21  usage: E
ssb  rsa4096/0xC6AF1016BBDEA800
     created: 2019-05-13  expires: 2022-04-21  usage: S
ssb  rsa4096/0x4C8A6A49D31C9CA1
     created: 2019-05-13  expires: 2022-04-21  usage: A
[ultimate] (1). Serghei Iakovlev <egrep@protonmail.ch>
[ultimate] (2)  Serghei Iakovlev <sadhooklay@gmail.com>
[ultimate] (3)  Serghei Iakovlev <mail@serghei.blog>
[ revoked] (4)  Serghei Iakovlev <serghei@phalcon.io>

Теперь необходимо сохранить все наши изменения. Команда save сохраняет изменения завершает сеанс редактирования ключей.

Теперь проверяем срок действия ключей еще раз:

$ gpg -k
/Users/egrep/.gnupg/pubring.kbx
-------------------------------
pub   rsa4096/0x1E0B5331219BEA88 2019-05-13 [C] [expires: 2022-04-21]
      Key fingerprint = EDAC 8D91 F82C 0BBD 261C  1329 1E0B 5331 219B EA88
uid                   [ultimate] Serghei Iakovlev <egrep@protonmail.ch>
uid                   [ultimate] Serghei Iakovlev <sadhooklay@gmail.com>
uid                   [ultimate] Serghei Iakovlev <mail@serghei.blog>
sub   rsa4096/0xDFA77DA0F7C016F2 2019-05-13 [E] [expires: 2022-04-21]
sub   rsa4096/0xC6AF1016BBDEA800 2019-05-13 [S] [expires: 2022-04-21]
sub   rsa4096/0x4C8A6A49D31C9CA1 2019-05-13 [A] [expires: 2022-04-21]

Что и требовалось получить — срок действия ключей продлён ещё на один год.

Финальным аккордом являются отправка ключа на сервер публичных ключей командой --send-keys. Эта процедура не обязательная, но желательна, если вы хотите, чтобы все ваши корреспонденты получили обновленную копию вашего публичного ключа:

$ gpg --send-keys 1E0B5331219BEA88
gpg: sending key 0x1E0B5331219BEA88 to hkp://ipv4.pool.sks-keyservers.net

2 comments

Игорь

Для этих целей [хранения шпаргалок] я решил себе выделить репозиторий на гитхаб, где в отдельном файле лежит шпаргалка по конкретной утилите/технологии. При этом можно даже воспользоваться подсветкой синтаксиса, если указать соответствующее расширение файла. Но в большинстве случаев, достаточно простого .md.

P.S. За шпаргалку спасибо, если понадобится, знаю где искать :)
P.S.S. Могу ошибаться, но по моему вы засветили свои emails.

Сергей

Игорь, спасибо за комментарий. У меня, как мне кажется накопилась критическая масса всяких мест, где я пишу заметки. По этому я решил собирать все здесь. Репозиториев у меня полно :)

P.S. Эти email-адреса не являются секретом, коль скоро их можно получить из моего публичного ключа. Например.