Как подписывать почтовую переписку GPG-ключом, используя PKCS#11-токены
Современные почтовые сервисы из года в год совершенствуют свою систему безопасности. Сначала появились механизмы аутентификации через СМС, сейчас уже совершенствуются механизмы машинного обучения для анализа подозрительной активности в почтовом ящике.
А что если кто-то получил заветный пароль от вашей почты и начал читать все ваши тайные переписки, а также писать направо-налево какую-то белиберду. Как добавить дополнительный уровень защиты и на этот случай? На помощь приходят GPG и смарт-карты.
GPG — это бесплатная программа с открытым исходным кодом, предоставляющая необходимые технологии для безопасной передачи сообщений. Работает она очень просто: это база данных со всеми открытыми ключами участников сети, с которыми вы хотите общаться. Этими ключами можно управлять: добавлять их, если завели нового знакомого, или удалять, если решили добавить кого-то в свой «черный список». Также GPG хранит открытый и закрытый ключ. Каждый ключ привязан к конкретному почтовому ящику и к конкретному пользователю в системе.
Но и это не все! GPG также предоставляет интерфейс для непосредственной работы с этими ключами. Вы можете: шифровать и расшифровывать письма; подписывать эти письма, чтобы все адресаты могли убедиться, что письмо было отправлено именно вами. Функциональность эта достаточно объемна и более подробно об этом можно прочитать в официальной документации.
Теперь к самому сладкому: GPG предоставляет возможность работы со смарт-картами. То есть не обязательно хранить закрытый ключ на компьютере, его вполне можно носить на токене или карте и безопасно работать с почтой, где и когда это удобно. «Так это же просто флешка! Я и на флешке могу переносить закрытый ключ», — сказал бы кто-то не совсем знакомый с принципом работы токенов. Токен — это не просто устройство, хранящее ключ. Это целая система, способная осуществлять криптографические операции внутри себя, не выгружая при этом закрытый ключ. Таким образом, закрытым ключом сможет воспользоваться только тот человек, который обладает токеном и знает секретный пароль (PIN-код) от него.
В настоящее время GPG работает только со смарт-картами, которые поддерживают интерфейс OpenPGP SmartCard. А для смарт-карт, поддерживающих интерфейс PKCS#11, есть решение, заключающееся в использовании PKCS#11 демона смарт-карт. Данный демон эмулирует работу со смарт-картами, работающими через интерфейс PKCS#11 так, как будто они поддерживают интерфейс OpenPGP. Таким образом, при правильной установке и настройке мы сделаем возможным использование ключей и сертификатов, хранящихся, например, на Рутокен ЭЦП PKI или Рутокен ЭЦП 2.0. Рутокен ЭЦП PKI в данном случае более предпочтителен, т.к. оптимизирован для работы с RSA.
Также далее будут представлены инструкции для интеграции GPG в популярные почтовые клиенты, такие как Thunderbird, KMail, Outlook и стандартный почтовый клиент Mail на macOS. Данная интеграция поможет людям, получившим от вас письмо, понимать, что письмо было действительно отправлено вами.
Заинтересовало? Тогда поехали! Пользователям Windows, которые захотят пойти путем шаманов и собрать демона с нуля, желательно запастись терпением…
Linux
Установите необходимые пакеты (используйте строчку в зависимости от системы, в которой вы работаете, первая — для red hat, вторая — для debian):
sudo apt-get install gpg opensc libpkcs11-helper1-dev openssl libgpg-error-dev libassuan-dev libgcrypt20-dev autoconf pkg-config # Debian
sudo yum instal gnupg2 gnupg-pkcs11-scd opensc # Red Hat
Удостоверьтесь, что версия:
gpg >= 2.1.19
gnupg-pkcs11-scd > 0.9.2
Для debian, возможно, потребуется скачать и установить последний релиз демона pkcs11 смарт-карт gnupg-pkcs11-scd из репозитория.
Установить его можно с помощью следующей команды:
autoreconf -i && ./configure --prefix /usr && make -j 4 && sudo make install
Установите librtpkcs11ecp.so из пакета, который можно скачать отсюда.
В файле ~/.gnupg/gpg-agent.conf запишите:
scdaemon-program /usr/bin/gnupg-pkcs11-scd
Во втором файле ~/.gnupg/gnupg-pkcs11-scd.conf напишите:
providers rutoken
provider-rutoken-library /usr/lib64/librtpkcs11ecp.so
Windows
Итак, сначала опишу ситуацию и объясню, в чем собственно состоит сложность. Дело в том, что демон gnupg-pkcs11-scd зависит от множества таких библиотек, как libgnupg-error, libassuan, openssl, pkcs11-helper, libgcrypt. И если в Linux эти библиотеки можно было получить с помощью щелчка пальцев (с помощью менеджеров пакетов), то под windows не все так просто, и некоторые пакеты необходимо собирать вручную потом и кровью.
К счастью, мы это уже проделали за вас и собрали готовый архив, содержащий все эти библиотеки в собранном виде. Он был протестирован на чистой системе. Так что если вы нам доверяете, то можете использовать готовую версию демона. Если же вы не хотите простой жизни, то снизу представлена инструкция по ручной сборке библиотеки с нуля.
Настройка с уже собранным демоном
В первую очередь, необходимо установить Gpg4Win с сайта.
Установим Драйвер Рутокен отсюда.
Скачаем собранную версию демона, ее можно взять отсюда.
Поправим файлы конфигурации, лежащие в %APPDATA%/gnupg. В gpg-agent.conf нужно записать:
scdaemon-program C:/HERE_IS_PATH_TO/gnupg-pkcs11-scd.exe
Во втором файле — gnupg-pkcs11-scd.conf напишем:
providers rutoken
provider-rutoken-library C:/Windows/System32/rtPKCS11ECP.dll
Сборка с нуля
Welcome to the club, buddy!
Приступим к самой сложной части данной статьи. Попробуем собрать pkcs11 демона смарт-карт для Windows. Казалось бы, какие тут сложности, взял и собрал. Но всегда есть подводные камни, давайте взглянем на них.
В первую очередь необходимо установить Gpg4Win с сайта и msys2, который можно взять отсюда.
После установки запустим в терминал msys2.
Ну что же, пришло время рассказать, в чем состоит основная сложность. Дело в том, что для сборки gnupg-pkcs11-scd требуется множество библиотек, от которых зависит данный демон. И если под Linux и macOS их можно получить просто из менеджеров пакетов уже в собранном виде, то для винды заранее собранных библиотек уже не так много. Тем не менее, одну из них все-таки можно получить, для этого введем последовательно команды:
pacman -Syuu
После нее необходимо будет перезапустить терминал.
pacman -S --needed git base-devel mingw-w64-i686-toolchain man2html pkg-config openssl-devel
Босс Данки Конг (libgpg-error)
Скачаем libgpg-error с сайта и разархивируем.
И соберем библиотеку:
./configure --with-cygwin-native
make
make install
Voilà! Первый босс повержен!
Босс Баузер (libassuan)
Скачаем libassuan с сайта, разархивируем и выполним:
./configure --with-cygwin-native
make
make install
Босс Вертолет (pkcs11-helper)
Скачаем pkcs11-helper с сайта и разархивируем.
Приступим к сборке библиотеки pkcs11-helper:
autoreconf --install
./configure --with-cygwin-native
make
make install
Босс Кибердемон (libgcrypt)
Скачаем libgcrypt с сайта, разархивируем и выполним:
./configure --with-cygwin-native
make
make install
Босс паук, паук огромный (gnupg-pkcs11-scd)
Испугались? Не бойтесь! Если вы прошли предыдущих боссов, то и с этим не будет проблем.
Скачиваем последнюю версию из репозитория и выполним команду:
autoreconf --install
./configure --with-cygwin-native
make
make install
Fatality
Установим Драйверы Рутокен отсюда.
Поправим файлы конфигурации, лежащие в %APPDATA%/gnupg. В gpg-agent.conf нужно записать:
scdaemon-program C:/msys32/mingw32/bin/gnupg-pkcs11-scd.exe
Во втором файле — gnupg-pkcs11-scd.conf напишем:
providers rutoken
provider-rutoken-library C:/Windows/System32/rtPKCS11ECP.dll
macOS
Установим brew отсюда.
Далее, используя его, поставим gpg и gnupg-pkcs11-scd:
brew install gpg gnupg-pkcs11-scd
Далее установим библиотеку librtpkcs11ecp отсюда.
В файле конфигурации ~/.gnupg/gpg-agent.conf впишем:
scdaemon-program /usr/local/lib/gnupg-pkcs11-scd
В файле конфигурации ~/.gnupg/gnupg-pkcs11-scd.conf впишем:
providers rutoken
provider-rutoken-library /usr/local/lib/librtpkcs11ecp.so
Ура! Теперь вы здесь! Проверим, что все настроено успешно.
Для начала удостоверьтесь, что на токене находятся только RSA-ключи, ибо наличие ГОСТ- ключей сделает невозможным работу с токеном. Лучшим вариантом будет вообще удалить все ключи с токена и создать только одну пару RSA-ключей и сертификат для него (самоподписанный или подписанный другим сертификатом).
Сгенерировать их можно, например, через веб-сервис управления ключами и сертификатами, SDK или используя утилиту командной строки pkcs11-tool
Теперь отключим gpg-agent. Это можно сделать через gpgconf. На всех платформах к данному моменту он уже должен быть поставлен: на Linux и macOS содержится в пакетах gpg, на Windows поставляется внутри Gpg4Win. Введем:
gpgconf --kill gpg-agent
Проверим, что токен откликается:
gpg --card-status
Правильный вывод должен выглядеть примерно так:
[lo1ol@localhost .gnupg]$ gpg --card-status
Application ID ...: D2760001240111503131CAE8D55A1111
Version ..........: 11.50
Manufacturer .....: unknown
Serial number ....: CAE8D55A
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: 1R 1R 1R
Max. PIN lengths .: 0 0 0
PIN retry counter : 0 0 0
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]
Если отклика не происходит, попробуйте обратиться к демону через gpg-agent. Запустите gpg-agent сервер и подключитесь к демону:
gpg-agent --server
SCD LEARN
Если вы получили ошибку Bad certificate, то вероятно проблема в том, что на токене лежат сертификаты, не поддерживаемые GPG. Правильный вывод выглядит следующим образом:
[lo1ol@localhost .gnupg]$ gpg-agent --server
OK Pleased to meet you
SCD LEARN
....
S KEYPAIRINFO 892E053AE031FC23F3E7CCC73BC60859F11F6B90 Aktiv\x20Co\x2E/Rutoken\x20ECP/3ac67ae9/Rutoken\x20ECP\x20\x3Cno\x20label\x3E/45
OK
Сначала надо узнать хеш сертификата на токене или смарт-карте, его можно узнать выполнив команду:
gpg-agent --server
SCD LEARN
Он должен отобразиться сразу напротив одной из выделенных строк, начинающихся на S KEYPAIRINFO. Например, в строке:
S KEYPAIRINFO 892E053AE031FC23F3E7CCC73BC60859F11F6B90 Aktiv\x20Co\x2E/Rutoken\x20ECP/3ac67ae9/Rutoken\x20ECP\x20\x3Cno\x20label\x3E/45
Хешем будет 892E053AE031FC23F3E7CCC73BC60859F11F6B90. Запомним его, зарегистрируем сертификат и его ключи в GPG. Для этого введем команду:
gpg --expert --full-generate-key
Далее нам будет предложено, какой тип ключа мы хотим получить. Выбираем импорт существующего RSA ключа (13 опция):
lo1ol@lo1ol-VirtualBox:~$ gpg --expert --full-generate-key
gpg (GnuPG) 2.2.4; Copyright (C) 2017 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.
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)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(9) ECC and ECC
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(13) Existing key
Your selection? 13
Теперь нас попросят ввести хеш сертификата данного ключа:
Enter the keygrip: 892E053AE031FC23F3E7CCC73BC60859F11F6B90
Далее нам предложат выбрать опции ключа, указать логин и e-mail пользователя ключа. Выбираем такие же, как снизу. Каждому ключу нужно указывать тот e-mail, для которого он будет использован:
Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection?
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)
Key does not expire at all
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: lo1ol
Email address: lo1ol@mail.ru
Comment:
You selected this USER-ID:
"lo1ol "
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
Параллельно нам будет предложено ввести пароль от токена. Успешный вывод выглядит следующим образом:
gpg: /home/lo1ol/.gnupg/trustdb.gpg: trustdb created
gpg: key 676E42AAAFBCF227 marked as ultimately trusted
gpg: directory '/home/lo1ol/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/lo1ol/.gnupg/openpgp-revocs.d/0CD2B9CEE398990609D6C164676E42AAAFBCF227.rev'
public and secret key created and signed.
pub rsa2048 2019-10-25 [SCE]
0CD2B9CEE398990609D6C164676E42AAAFBCF227
uid lo1ol
Заметим, что почта, которую мы указали — это почта для отправки сообщений.
Важным моментом является то, что сертификат, который лежит на токене, и сертификат, который был занесен в базу GPG — это два разных сертификата и они имеют разный формат. GPG имеет свой тип сертификатов (не X.509), который хранит в себе информацию: о ключе, электронный адрес владельца, имя владельца и т.д. Сертификат, лежащий на токене, по сути используется только для распознавания ключей перед добавлением их в базу GPG.
В GPG также можно подписывать, например, с помощью Kleopatra, сертификаты ключей, которые у вас есть. Но повторюсь, эти сертификаты никак не будут связаны с теми, что лежат внутри токена в формате X.509.
Настройка Thunderbird
В первую очередь, опишем использование GPG ключей в Thunderbird. Дело в том, что это один из немногих почтовых клиентов, которые могут работать на Linux, Windows и macOS. Давайте попробуем его настроить (за основу была взята инструкция).
Установка
В первую очередь, скачаем и установим его. В Linux и macOS все просто:
sudo apt-get install thunderbird # Debian
sudo yum install thunderbird # Red Hat
brew cask install thunderbird #
Для Windows и macOS установщик можно скачать c официального сайта. Скачиваем установщик, далее устанавливаем Thunderbird, изи бризи.
После того как мы поставили Thunderbird, необходимо добавить туда почтовый ящик, который мы хотим использовать, и для которого мы добавили ключи и сертификат в GPG.
Добавление плагина для работы с GPG
Пришло время добавить плагин Enigmail для интеграции Thunderbird c GPG. Для этого установим плагин ENIGMAIL. Переходим на вкладку Дополнения и нажимаем на них:
В поиске ищем плагин Enigmail и нажимаем на кнопку «Добавить в Thunderbird»:
Когда плагин установится, он предложит добавить существующие ключи. Согласимся с ним и нажмем на кнопку «Apply my Keys».
Почти все готово. Осталось только привязать ключи к учетным записям почты.
Привязка ключей к учетным записям
Перейдем в настройку учетной записи:
Во всплывшем окне выберем вкладку «Защита OpenPGP» и выберем ключ, который мы хотим использовать для этой почти. Также можно настроить опции по умолчанию.
Все готово, и все в сборе!
Тебя не хватает, тебя не хватает…
Старичок, идем на пикничок!
Проверка работоспособности
Пришел момент истины. Проверим, что вся система работает корректно. Перезагрузим Thunderbird и попробуем отправить сообщение какому-нибудь пользователю, публичный ключ которого у меня зарегистрирован в GPG. Для этого я добавил еще одну учетную запись, чтобы проверить результат. Создадим новое письмо:
Убедимся, что опция шифрования письма (если это необходимо) и опция подписи включены. Также в процессе отправки нас вероятно попросят ввести пароль токена.
Проверим, что отправленное письмо пришло и удачно расшифровывается, а подпись проходит проверку.
Как можно видеть, все работает успешно!
Настройка Kmail
Для начала скачаем kmail из репозитория:
sudo apt-get install kmail # Debian
sudo yum install kmail # Red Hat
Запустим KMail. Введем данные учетной записи почты и нажмем «Add Account».
Во всплывшем окне выберем «Use GPG».
Выбираем ключ, который мы хотим использовать для этого почтового ящика:
Настроим идентификатор личности в настройках:
Установим ключи для подписи и шифрования:
Установим email:
Попробуем отправить письмо. Убедитесь, что выставлены опции подписи и шифрования.
Проверим, что полученное письмо успешно проходит проверку подписи и расшифровывается:
Как можно увидеть, все отработало успешно!
Настройка Outlook
Тут все просто, т.к. все, что нужно для работы у вас уже есть и настроено: плагин GPGol содержался в Gpg4Win и настроился автоматически. Попробуем просто отправить сообщение, указав в опциях, что его нужно зашифровать и добавить подпись.
Посмотрим на пришедшее письмо. Можно увидеть, что подпись прошла проверку и письмо расшифровывалось.
Настройка клиента Mail
Тиму Куку заплатите,
Чеканной монетой…
Чеканной монетой…
Данный способ, традиционно для Apple, является платным, и подойдет, если вы готовы потратить свои честно нажитые шекели на плагин GPG Suite. Если же вы дорожите своим золотом, то можете пользоваться бесплатным вариантом — Thunderbird.
Переходим на сайт GPG Suite и скачиваем последнюю версию данного пакета.
После установки необходимо будет активировать плагин GPGMail. Для этого переходим в настройки Mail > Preferences > General > Manage Plug-Ins и активируем GPGMailLoader.mailbundle.
Плагин активирован. Попробуем отправить тестовое письмо. Заметьте, что мы установили опцию подписи сообщения и его шифрования.
И проверим, что расшифрование и проверка подписи прошли успешно.
Ура, мы справились!
Kleopatra предоставляет пользователю удобный графический интерфейс для работы с GPG, такие как: подпись, шифрование, проверка подписи, расшифрование и т.п. На Windows она ставится вместе с Gpg4Win, а на Linux ее можно поставить через менеджер пакетов:
sudo apt-get install kleopatra # Debian
sudo yum install kleopatra # Red Hat
Запустим ее и увидим, что работа в программе интуитивно понятна)
Взаимодействие с GPG ключами, хранящимися на смарт-карте, почти ничем не отличается от использования ключей, лежащих в файловой системе. Но в то же время значительно снижается вероятность утечки ключей и, как следствие, несанкционированное чтение ваших писем.
В целом, использование GPG для повышения целостности и конфиденциальности вашей информации является почти прозрачным для пользователя и интегрировано со многими современными почтовыми клиентами.