Шпаргалка по основным командам 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 https://keyserver.ubuntu.com
Сервер ключей, на который следует отправить ключи, указывается параметром командной строки --keyserver
.
$ gpg --keyserver hkps://keys.openpgp.org --send-keys 1E0B5331219BEA88
gpg: sending key 0x1E0B5331219BEA88 to hkps://keys.openpgp.org
Существуют несколько популярных серверов ключей. Основные серверы ключей синхронизируются друг с другом, поэтому лучше выбрать ближайший к вам и регулярно использовать его для отправки и получения ключей.
На момент написания этой шпаргалки, мне удалось успешно отправить ключ на следующие сервера: