Введение в GnuPG
Это короткое пособие объясняет лишь некоторые базовые возможности GnuPG, больше информации можно найти fвоспользовавшись командой man gpg2.
Немного теории
GnuPG - это реализация программы PGP (Pretty Good Privacy), которая состоит из пары ключей: public и private. Особенностью данного метода шифрования является подход, когда файл может быть зашифрован для конкретного получателя используя его public ключ, когда для расшифровки файла, в свою очередь, понадобятся оба (public и private) ключа. Таким образом, идея заключается в том, чтобы предоставить ваш public ключ вашим друзьям или коллегам, но хранить private ключ надежно защищенным и не предоставлять его никому.
В GnuPG оба ваших ключа ассоциированы с id, который состоит из вашего имени, адреса электронной почты и комментария. Когда вы указываете получателя зашифрованного файла, вы можете использовать имя или адрес электронной почты (я буду использовать email).
Ваш private ключ защищён паролем и соответственно, требует ввода пароля для использования. Это добавляет ещё один уровень авторизации, в случае, если кто-то получит физический доступ к вашему компьютеру.
Установка
Если вы используете Linux, то скорее всего в вашем дистрибьютиве уже есть предустановленные пакеты GnuPG. Я использую Fedora 27 и в нём присутствует целых две версии GnuPG. Проверить это можно введя в консоли команду gpg --version или gpg2 --version. Я использую gpg2, так как в моей системе есть ряд пакетов (например pass), которые имеют зависимости от gpg2. Если пакет gpg2 отсутствует в вашей системе, то его можно установить используя ваш пакетный менеджер, для Fedora например это выглядит так: sudo dnf install gnupg2.
Генерируем ключи
Для того чтобы сгенерировать новую пару ключей, вам нужно дать команду gpg2 с атрибутом --full-gen-key. Вам будет предложено несколько вариантов шифрования:
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection?
В большинстве случаев первый вариант является подходящим. Пара RSA/RSA позволит вам подписывать ваши коммуникации, а также шифровать файлы. Следующий шаг - выбор размер ключа:
RSA keys may be between 1024 and 4096 bits long.
Larger is almost always recommended here, however your use case and security models may dictate otherwise.
What keysize do you want? (2048)
Вариант предложенный по умолчанию (2048), подойдет большинству пользователей и представляет очень высокий уровень безопасности при шифровании. Далее нам нужно выбрать срок действия ключей:
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)
Значение по умолчанию предполагает бессрочный срок действия ключа. Выберите подходящий срок (после генерации ключа, это значение можно будет изменить), после чего gpg2 потребует подтвердить корректность введенной информации:
Is this correct (y/n)?
Следующий шаг после подтверждения - ввод своего реального имени, электронной почты и опционально - комментария. Также на этом шаге потребуется ввести пароль для ключа. После ввода всех нужных данных и подтверждения их корректности gpg2 сгенерирует пару ключей и выдаст информацию о новых ключах на экран:
pub 1024D/1C2BFG1D 2018-03-11 Evgenii A. Antipin <antipin@antipin.com>
Key fingerprint = 129C DG83 32ED C732 5A49 6884 2330 644E 2C2A FA1B
sub 1024g/AE3B22E 2018-03-11 [expires: 2020-03-11]
Теперь, когда процесс генерации завершен, у вас есть две коллекции ключей (keyrings): public keyring и private keyring. Ваша public коллекция ключей пока содержит только ваш собственный public ключ. Вы можете посмотреть ее введя команду gpg2 с аттрибутом --list-keys. Когда кто-либо еще предоставит вам свои public ключи, для того чтобы вы могли отправлять им зашифрованные файлы, эти ключи также появятся здесь.
Вы также можете посмотреть вашу private коллекцию ключей, которая содержит ваш private ключ, введя команду gpg2 с аттрибутом --list-secret-keys.
Шифрование файла
Теперь когда у нас есть пара ключей, мы можем шифровать файлы. Давайте попробуем сделать это. Создайте простой текстовый файл в удобной для вас директории:
echo 'this is my very secret file' > secret.txt
А теперь мы зашифруем файл secret.txt, явно указывая получателя как себя самого: технически мы можем сделать это, поскольку мы имеем наш собственный public ключ (а соответственно и ассоциированный с ним email) в нашей коллекции public ключей. Мы будем использовать параметр -e (encrypt) вместе с -r (recepient) и почтой получателя, завершая это именем файла, который мы будем шифровать:
gpg2 -e -r your@email.com secret.txt
Как вы можете видеть, в результате выполнения данной команды мы получили новый (зашифрованный) файл, с тем же самым именем, что и оригинальный, но с дополнительным расширением .gpg: secret.txt.gpg. Это кажется разумным решением, например, когда оба файла: оригинал и зашифрованная копия находятся в одном каталоге. Визуально можно сразу увидеть, какие файлы зашифрованы. Однако, если вы не хотите привлекать лишнего внимания к файлам с явным расширением .gpg, вы можете избавиться от него указав аргумент -o (output) и желаемое имя файла на выходе:
gpg2 -e -r your@email.com -о encrypted.txt secret.txt
В результате выполнения данной команды, на выходе мы получим зашифрованный файл encrypted.txt. Вы можете убедиться в этом, если попробуете просмотреть содержимое файла с помощью команды cat, в результате выполнения которой, вы увидите некоторое количество нечитаемых символов. Это и есть наш зашифрованный файл. Таким образом мы можем шифровать любые типы файлов, не только текстовые, а например изображения.
Также дополнительно, процесс шифрования скрывает информацию о типе файла из заголовков файла, шифруя ее. Это также помогает обеспечить дополнительную безопасность зашифрованного файла. Обратите внимание, как в примере ниже, зашифрованная картинка в формате png более не определяется системой как графический файл, её тип отображается просто как data:
file picture.png
picture.png: PNG image data, 1319 x 968, 8-bit/color RGB, non-interlaced
gpg2 -e -r your@email.com -o encrypted_picture.png picture.png
file encrypted_picture.png
encrypted_picture.png: data
Расшифровка файла
Теперь когда мы успешно зашифровали файл, мы должны научиться расшифровывать его. Чтобы расшифровать файлы, мы используем аргумент -d (decrypt), как в примере ниже:
gpg2 -d secret.txt.gpg
You need a passphrase to unlock the secret key for
user: "Your Name <your@email.com>"
1024-bit ELG-E key, ID 52443CA3, created 2018-03-11 (main key ID 0EF6B359)
Enter passphrase: your passphrase
gpg2: encrypted with 1024-bit ELG-E key, ID 52443CA3, created 2018-03-11
"Your Name <your@email.com>"
this is my very secret file
GnuPG запросит ваш пароль, который вы задали в процессе генерации ключей. Если вы ввели пароль верно, содержимое файла будет выведено путем стандартного вывода (на экран). Эта не самое практичное решение, тем более, когда речь идет о нетекстовых файлах, поэтому мы воспользуемся уже знакомым вам атрибутом -o (output), дабы явно указать имя файла в который будет расшифровано содержимое нашего зашифрованного текстового файла. Ровно так же, как и в примере с шифрованием. В данном случае мы указываем файл decrypted.txt как файл в который будет расшифровано содержимое файла secret.txt.gpg
gpg2 -d -o decrypted.txt secret.txt.gpg
Это вся базовая информация, которую вам нужно знать, чтобы шифровать и дешифровать файлы для себя. Таким образом теперь вы можете шифровать любые ваши данные и безопасно их хранить, не изучая каких-то дополнительных команд, пользуясь лишь знаниями полученными здесь.
Если же вы желаете шифровать файлы для других людей, или принимать зашифрованные файлы от других людей, то вам стоит научиться импортировать и экспортировать public ключи.
Импорт и экспорт public ключей
Первое что мы должны сделать, если мы хотим чтобы другие люди могли отправлять нам зашифрованные файлы - это экспортировать наш public ключ в отдельный текстовый файл. Который мы бы могли им предоставить, дабы они добавили его в свои коллекции public ключей, получив таким образом возможность шифровать файлы, перед тем, как отправить их вам.
Атрибут -a (armor) в команде позволит нам экспортировать ключ в ASCII формате, дабы мы могли его открыть, прочитать, опубликовать. По умолчанию же, экспорт ключей производится в двоичный формат.
gpg2 -a -o publickey.txt --export your@email.com
Данная команда сохранила наш public ключ в файл publickey.txt. А теперь давайте посмотрим как импортировать этот ключ на другую машину, чтобы пользователь другого компьютера мог зашифровать файлы для нас (мы будем использовать тот же самый процесс когда будем добавлять ключи других пользователей в свои коллекции и шифровать файлы для них). Сначала, давайте посмотрим что будет если мы попытаемся зашифровать файл, не имея нужного (т.е. соответствующего пользователю) ключа в нашей коллекции ключей:
echo 'a secret from vasya' > vasyassecret.txt
gpg2 -e -r your@email.com vasyasecret.txt
gpg2: your@email.com: skipped: public key not found
gpg2: vasyasecret.txt: encryption failed: public key not found
Здесь мы создали новый текстовый файл на другом компьютере, но когда мы попытались зашифровать файл, gpg2 уведомила нас о том, что мы не можем этого сделать, так как у нас нет подходящего ( т.е. соответствующего заявленному в команде адресу email) ключа. Соответственно, нам нужно импортировать нужный ключ (тот что мы экспортировали ранее на другой машине) и попробовать снова:
gpg2 --import publickey.txt
/home/vasya/.gnupg/trustdb.gpg: trustdb created
gpg2: key 1C2BFG1D: public key "Your Name <your@email.com>" imported
gpg2: Total number processed: 1
gpg2: imported: 1
Следующая вещь, которую мы должны сделать, это установить уровень доверия новому ключу, это будет говорить gpg2 о том, насколько мы доверяем владельцу ключа:
gpg2 --edit-key your@email.com
gpg (GnuPG) 2.2.5; Copyright (C) 2018 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.
pub 1024D/1C2BFG1D created: 2018-03-11 expires: never usage: CS
trust: unknown validity: unknown
sub 2048g/A3F6ED8D created: 2018-03-11 expires: never usage: E
[ unknown] (1). Your Name <your@email.com>
Command> trust
pub 1024D/1C2BFG1D created: 2018-03-11 expires: never usage: CS
trust: unknown validity: unknown
sub 2048g/A3F6ED8D created: 2018-03-11 expires: never usage: E
[ unknown] (1). Your Name <your@email.com>
Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)
1 = I don’t know or won’t say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
pub 1024D/1C2BFG1D created: 2018-03-11 expires: never usage: CS
trust: ultimate validity: unknown
sub 2048g/A3F6ED8D created: 2018-03-11 expires: never usage: E
[ unknown] (1). Your Name <your@email.com>
Please note that the shown key validity is not necessarily correct
unless you restart the program.
Command> quit
Теперь, когда мы импортировали ключ и установили уровень доверия, мы можем зашифровать файл без ошибок:
gpg2 -e -r your@email.com vasyasecret.txt
И наконец, для чистоты эксперимента, давайте попробуем расшифровать этот файл на первом компьютере, дабы удостовериться в том, что все прошло успешно. И конечно же, в примере ниже видно, что мы не можем расшифровать данный файл на машине из предыдущего примера, так как на ней отсутствует private ключ, только импортированный нами ранее, public ключ:
gpg2 -d vasyassecret.txt.gpg
gpg: encrypted with 2048-bit ELG-E key, ID A3F6ED8D, created 2018-03-11
"Your Name <your@email.com>"
gpg: decryption failed: secret key not available
gpg2 -d vasyassecret.txt.gpg // передаем файл на первую машину и снова пробуем
You need a passphrase to unlock the secret key for
user: "Your Name <your@email.com>"
Enter passphrase: my passphrase
2048-bit ELG-E key, ID A3F6ED8D, created 2018-03-11 (main key ID 32CDE571)
gpg: encrypted with 2048-bit ELG-E key, ID A3F6ED8D, created 2018-03-11
"Your Name <your@email.com>"
a secret from vasya
Делаем резервные копии и восстанавливаем ключи
Представьте, что вы зашифровали большие объемы важной информации, а потом ваш жесткий диск благополучно помер, вместе с вашими ключами. В подобном случае, у вас не было бы абсолютно никакой реальной возможности восстановить ваши данные.
Чтобы этого не случилось, нужно иметь резервные копии ваших ключей. А для того чтобы сделать копии, нам нужно уметь экспортировать оба вида ваших ключей. Ранее мы уже рассмотрели как импортировать и экспортировать public ключи, так что нам осталось научиться делать то же самое с private ключами.
С помощью команд ниже мы экспортируем оба наших ключа:
gpg2 --export -a -o mypublickey.txt your@email.com
gpg2 --export-secret-key -a -o myprivatekey.txt your@email.com
Теперь, когда мы имеем оба наших ключа в виде файлов, мы можем их сохранить в безопасное место, или даже распечатать (вот для чего нужна была опция -a, файлы ключей могут быть напечатаны в текстовом формате). В случае отказа носителя на котором будет сохранена копия, мы можем набрать содержимое ключа с распечатанного листа. Самое главное здесь - это хранить всю информацию о ключах в безопасном месте.
Представим, что случилось страшное и наш жесткий диск, таки ушел в отказ. Мы достаем носитель с резервными копиями ключей и импортируем обе копии (используем атрибут --import для обоих ключей, gpg автоматически определит тип каждого из них):
gpg2 --import myprivatekey.txt
gpg: directory `/Users/user/.gnupg' created
gpg: new configuration file `/Users/user/.gnupg/gpg.conf' created
gpg: WARNING: options in `/Users/user/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/Users/user/.gnupg/secring.gpg' created
gpg: keyring `/Users/user/.gnupg/pubring.gpg' created
gpg: key A3F6ED8D: secret key imported
gpg: /Users/user/.gnupg/trustdb.gpg: trustdb created
gpg: key 34BEE591: public key "Your Name <your@email.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
gpg2 --import mypublickey.txt
gpg: key A3F6ED8D: "Your Name <your@email.com>" 1 new signature
gpg: Total number processed: 1
gpg: new signatures: 1
Вы можете видеть что, когда мы импортировали первый (private) ключ, все файлы конфигураций, коллекции ключей были заново созданы, таким же образом как если бы мы использовали атрибут --gen-key первый раз. Все что вам осталось сделать теперь - это заново задать уровень доверия своему public ключу (вы уже знаете как это делать).
И в завершение, давайте попробуем расшифровать файл созданный нами ранее, дабы убедиться в том, что импорт private ключа прошел успешно и мы действительно можем его использовать:
gpg2 -d vasyassecret.txt.gpg
You need a passphrase to unlock the secret key for
user: "Your Name <your@email.com>"
Enter passphrase: my passphrase
2048-bit ELG-E key, ID A3F6ED8D, created 2018-03-11 (main key ID 32CDE571)
gpg: encrypted with 2048-bit ELG-E key, ID A3F6ED8D, created 2018-03-11
"Your Name <your@email.com>"
a secret from vasya