Инструкции проверены на следующей версии:

$ gpg --version | head -n 2
gpg (GnuPG) 2.2.19
libgcrypt 1.8.5

Можно ожидать что на следующих версиях инструкции будут работать аналогично.

Создаём ключи

Выбрать алгоритм для ключей по умолчанию

Если нужны новые и модные EdDSA и Ed25519:

echo 'default-new-key-algo:0:"ed25519' | gpgconf --change-options gpg

Если вам ближе старый и проверенный RSA-4096:

echo 'default-new-key-algo:0:"rsa4096' | gpgconf --change-options gpg

Резервное копирование

Если вы раньше пользовались GnuPG, стоит сделать резервную копию каталога с ключами и настройками, на случай если что-то пойдет не так:

(umask 077; tar -cf ~/gnupg-backup$(date +%s).tar -C ~ .gnupg)

После успешного окончания всех работ эту резервную копию лучше удалить либо используя утилиту shred из coreutils, либо srm из пакета secure-delete.

Создаём первичный ключ

Сгенерируем первичный ключ использующий RSA-4096 командой:

gpg --quick-generate-key "John Doe <username@test.ru>" rsa4096 cert

Для EdDSA команда будет аналогичная:

gpg --quick-generate-key "John Doe <username@test.ru>" ed25519 cert

Не все OpenPGP-совместимые смарт-карты поддерживают ключи EdDSA. Если планируетя перенос первичного ключа на смарт-карту, это надо иметь ввиду.

Резервная копия первичного ключа и сертификата отзыва

Сделаем резервную копию ключа:

gpg --armor --export-secret-keys > gpg-backup.txt

Резервная копия будет защищена тем же паролем, что вы устанавливали раньше.

Резервная копия сертификата отзыва:

tar cvf gpg-revocs.tar --directory=${GNUPGHOME:-~/.gnupg}/openpgp-revocs.d/ .

Проверим что всё экспортировалось как надо:

gpg --dry-run --import --verbose < gpg-backup.txt
tar xfO gpg-revocs.tar | sed s/:-/-/ | gpg --dry-run --import --verbose

Первая команда выведет что-то вроде:

gpg: sec  rsa4096/2E8C6C9B8BE369BE 2020-02-22  John Doe <username@test.ru>
gpg: Total number processed: 1
gpg:       secret keys read: 1

Вторая не спросит пароля, выведет:

gpg: armor header: Comment: This is a revocation certificate
gpg: Total number processed: 1
gpg:    new key revocations: 1

Резервная копия ключа для распечатки

Распечатать резервную копию секретной части ключа, можно с помощью утилиты Paperkey. Она же поможет собрать всё обратно.

gpg --export-secret-keys | paperkey

Копия ключа "для распечатки" будет защищена тем же самым паролем, что и сам ключ, а распечатка не содержит публичной части ключа. Публичную часть ключа нужно где-то хранить отдельно.

Проверка ключей без WoT

Перейти на схему TOFU или Trust On First Use, а ещё точней схема TOFU+GPG, можно так:

echo 'trust-model:0:"tofu+pgp' | gpgconf --change-options gpg

Выбрать сервер ключей по умолчанию

Перейти на использование keys.openpgp.org можно так:

echo 'keyserver:0:"hkps%3A//keys.openpgp.org' | gpgconf --change-options gpg

В новых версиях этот сервер используем по умолчанию без всяких настроек.

Использование GnuPG вместе с Git

Включаем автоподпись коммитов:

git config --global commit.gpgsign true

Проверяем:

git commit 
git log --show-signature -1

Выгрузка ключей на сервисы

Сослаться на ключи на GitHub:

https://github.com/<user>.gpg

Keybase - централизованная альтернатива ключевым серверам

После установки клиента Keybase, выгрузить публичную часть ключа:

keybase pgp select

Загрузить обновленную публичную часть:

keybase pgp update

Получить ключ знакомого, или, например, автора этой шпаргалки:

keybase follow sanmai; keybase pgp pull

Выгруженные ключи можно скачать по ссылке вида:

https://keybase.io/<user>/pgp_keys.asc

Пароли по умолчанию для OpenPGP Card

Пароли по умолчанию для смарт-карт и токенов:

  • PIN пользователя: 123456
  • PIN администратора: 12345678 (без 9 на конце)

Эмулятор OpenPGP Card

docker pull ionsago/openpgp-card
docker run -d --rm --name openpgp-card ionsago/openpgp-card
docker exec --user pgpcard --workdir /home/pgpcard -it openpgp-card /bin/bash

Проверить статус карты в эмуляторе:

gpg --card-status

Если нужно начать всё сначала, то:

docker kill openpgp-card

Настройка GnuPG под macOS

Пользователям macOS кроме самой GnuPG для интеграции с Keychain стоит установить pinentry-mac и включить её:

brew install gnupg pinentry-mac
echo pinentry-program $(brew --prefix)/bin/pinentry-mac >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

Использование GnuPG во временном окружении

Объясним GnuPG что нужно использовать другой каталог, отличный от стандартного:

export GNUPGHOME=$(mktemp -d)

Проверим что GnuPG действительно работает из другого каталога:

gpg --version | grep ^Home

Закрыть временное окружение:

gpgconf --kill all
unset GNUPGHOME

Подготовка смарт-карты OpenPGP к использованию

Проверим статус карты:

gpg --card-status

Если у вас YubiKey и ошибка No such device то может помочь добавить директиву reader-port Yubico YubiKey в scdaemon.conf.

Можно требовать PIN-код для каждой подписи, а не только при первом использовании.

(echo admin; echo forcesig; echo quit) |
    gpg --command-fd 0 --card-edit 

Перенос ключа на карту

Для переноса ключа на карту вызовем:

(echo keytocard; echo y; echo 1; echo save) |
    gpg --command-fd 0 --edit-key username@test.ru

В процессе GnuPG спросит вас пароль от ключа, а затем PIN администратора смарт-карты, который по умолчанию 12345678.

Смена паролей у карты

Заменяем пароль у смарт-карты, сначала меняя пароль администратора, а потом пользователя:

(echo admin; echo passwd; echo 3; echo 1; echo q; echo quit) |
    gpg --command-fd 0 --card-edit

Пароль администратора меняем сначала так как для некоторых карт характерен так называемый admin-less режим, который активируется, если сначала менять PIN для пользователя. Такой режим может быть удобен если вы не хотите запоминать два разных пароля.

Ключ для подписей

Добавляем подключ для подписей со сроком действия в год.

read -r FPR GPGUID < <(gpg --list-options show-only-fpr-mbox --list-secret-keys)
gpg --quick-add-key $FPR - sign 1y

Первая команда исходит из того, что у вас только один первичный ключ, секретная часть которого находится на карте. Если несколько, то вместо $FPR подставьте ID ключа с карты.

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

Пробуем что-то подписать:

echo -n | gpg --sign | gpg --verify

Экспорт ключа на ключевой сервер

Экспорт делается одной командой:

gpg --export username@test.ru | curl -T - https://keys.openpgp.org

Затем переходите по ссылке и следуете инструкциям.

Экспорт ключей для сервисов

Перед такой операцией экспорта имеет смысл сжать ключи, удалив устаревшие подписи:

gpg --edit-key username@test.ru minimize clean save

Для сравнения, мой ключ до операции занимал 319 строк, а после - 244 строки. Если у вас новый ключ, то разницы вы можете не увидеть: эта операция больше имеет смысл для ключей, которые используются уже какое-то время.

Выгружаем ключ в файл:

gpg --armor --export > my_key.asc

И загружаем используя страницу настроек на GitHub и на GitLab.

Эту операцию нужно повторять после добавления новых подключей, и после продления сроков действия.

Обновить ключи в базе Keybase можно следующей командой:

keybase pgp update

Использование смарт-карты на другом компьютере

Публичную часть ключей нужно импротировать из файла, или получить с ключевых серверов или через Web Key Directory:

gpg --locate-keys username@test.ru
gpg --card-status

Также скачать ключ может сам GnuPG в режиме редактирования карты, по команде fetch.

Обновление ключей на ключевых серверах

Для ключевого сервера по умолчанию:

read -r FPR GPGUID < <(gpg --list-options show-only-fpr-mbox --list-secret-keys)
gpg --send-key $FPR

Для традиционной сети серверов:

gpg --keyserver hkps://hkps.pool.sks-keyservers.net --send-key $FPR

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

gpg --refresh-keys

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

Это можно сделать из одного места, для всех ключей сразу. Сначала для основного, а затем для всех вторичных, так:

read -r FPR GPGUID < <(gpg --list-options show-only-fpr-mbox --list-secret-keys)
gpg --quick-set-expire $FPR 1y
gpg --quick-set-expire $FPR 1y '*'

Если у вас несколько первичных ключей, вместо $FPR подставьте отпечаток вашего ключа.

Ключи с истекшим сроком действия

Посмотреть отозванные ключи, и ключи с истекшим сроком действия:

gpg --list-options show-unusable-subkeys --list-keys