Обзор
Эта статья родилась из простой задачи, мне нужно было передать файл с паролями с одного компьютера на другой через интернет. Можно сколько угодно говорить о шифровании в мессенджере и безопасных сервисах, которые “упрощают” нашу жизнь. Но факт остается фактом, если вы хотите действительно безопасно передать данные через интернет, придется погрузиться в шифрование. Я не специалист по информационной безопасности, мой интерес чисто обывательский. Первое правило здесь - каналы передачи данных всегда небезопасны. Второе - любой сервис с пользователями всегда будет целью для взломов и поиска уязвимостей.
PGP (Pretty Good Privacy) - одна из первых популярных реализаций шифрования с открытым ключом. У нее интересная история, особенно в части как правительство США пыталось запретить её экспорт. В итоге PGP стала коммерческим продуктом. Доступна бесплатная версия, основанная на том же стандарте, что и PGP. Она называется GnuPG (или GPG). Поскольку стандарт одинаковый, пользователи часто говорят «PGP-ключ» и «PGP-сообщение», хотя на самом деле используют GnuPG.
В виду своего возраста и распространенности, PGP одна из самых критикуемых реализаций. Но именно из-за этих двух факторов PGP является своего рода стандартом. Куча ошибок в нем уже были найдены и устранены и многие уже привыкли/знают как с ним работать. При использовании современных алгоритмов он дает неплохую криптоустойчивость, а к минусам можно отнести не самое простое управление, для которого требуется небольшое погружение.
Предположим, вы хотите отправить кому-то сообщение, содержащее деликатную информацию и не хотите, чтобы кто-то еще мог его прочитать. Лучший способ будет зашифровать сообщение специальным ключом, который будете знать только вы и получатель. Если атакующий перехватит сообщение, он не сможет ничего расшифровать. В наше время мы считаем “условно не сможет” потому что компьютерные мощности растут и, например, устаревшие алгоритмы шифрования могут быть взломаны как через уязвимости, так и методом перебора. Такой вариант называется системой с симметричным ключом. Они работают нормально, но есть проблема курицы и яйца, прежде чем отправить сообщение, нужно поделиться ключом, а как это сделать без секретного канала?
PGP решает именно эту проблему. Криптография открытого ключа позволяет безопасно делиться информацией, независимо на каком расстоянии и за какими границами вы находитесь и не требует установки изначального безопасного канала.
Шифрование и Дешифрование
Шифрование и дешифрование в криптографии публичным ключом опирается на пару математически уникальных ключей. Один называется публичный, а другой приватный. Публичный ключ предоставляет однонаправленную функцию, подобно висячему замку. Любой человек может его закрыть, но открыть только владелец закрытого ключа. Критическим моментом является защита приватного ключа, который используется для расшифровки сообщения, зашифрованного публичным ключом. Он должен всегда оставаться секретным, известным только владельцу. Картинка ниже иллюстрируется пример шифрования и дешифрования.
Если Ваня хочет послать зашифрованное сообщение Пете, ему нужен Петин публичный ключ. Это значит, что Петя должен им как-то поделиться, например в социальных сетях. Тогда Ваня сможет взять этот публичный ключ, зашифровать им сообщение и отправить любым, в том числе ненадежным каналом связи Пете. А Петя в свою очередь расшифрует сообщение своим приватным ключом.
Отпечатки
Одна из проблем с публичным ключами это самозванство. Нет легкого способа гарантировать, что определенный публичный ключ, опубликованный онлайн действительно принадлежит конкретному человеку. Атакующий может сгенерировать пару ключей и “подсунуть” свой публичный ключ, прикидываясь другим человеком.
Чтобы справиться с этой проблемой, в PGP существует механизм отпечатков. Отпечатки (Fingerprints) - это уникальный идентификатор, они генерируются в результате односторонней математической функции называемой хэширование. Односторонней значит что из отпечатка нельзя получить исходный ключ выполнив обратную процедуру (хэшировать можно любые данные, не только ключи). Результатом является цифробуквенная строка фиксированной длинны. Пользователи публикуют свои отпечатки на различных платформах. Например в социальных сетях, email подписях или даже печатают на визитках. Одним из способов также является публикация на специальном сервере-справочнике (например keybase.io).
У меня в блоге есть отдельная страница, на которой можно скачать мой публичный PGP ключ и найти отпечаток. Этот же отпечаток указан в био в моем Twitter аккаунте. Скачав публичный ключ и импортировав его к себе (об этом еще будет позже), можно повторить процесс генерации отпечатка самостоятельно и сравнить его с тем, что указан публично. Таким образом вы убедитесь что публичный ключ действительно принадлежит этому человеку. Но будьте внимательны, злоумышленник может подменить отпечатки тоже.
Публикация отпечатка в разных источниках увеличивает стоимость атаки для злоумышленника, который пытается прикинуться другим человеком. Ему придется взломать каждую платформу, на которой опубликован настоящий отпечаток, чтобы подменить его своим собственным. Выложив отпечаток на разных платформах, можно также легко идентфицировать, если какая-то из них была скомпрометирована.
Подпись сообщений
Другой компонент PGP - подпись сообщений. Это процесс удостоверения сообщения уникальной цифровой подписью.
Ваня хочет отправить сообщение Пете и подтвердить, что сообщение действительно пришло от него, а также, что оно не было модифицировано по пути. Для этого он подписывает его. Чтобы подписать сообщение PGP хэширует его, чтобы длина подписи не зависела от размера сообщения, затем шифрует хэш используя приватный ключ. Расшифровать подпись можно только публичным ключом Вани, т.е. если у Пети получилось это сделать, он будет уверен, что сообщение пришло именно от Вани. Затем, Петя может сам создать хэш сообщения и сравнить его с тем, что получился в результате дешифрования подписи, таким образом убедившись, что сообщение не было изменено в процессе передачи.
Будьте внимательны, подписывание сообщения позволяет убедиться в аутентичности и целостности данных, но не защищает само сообщение. Другими словами, если вы только подписали сообщение, оно будет передано в открытом виде и кто угодно сможет его прочитать. Чтобы сообщение было конфиденциальным, после подписания его надо зашифровать публичным ключом получателя и отправить в шифрованном виде.
Сочетание подписания с шифрованием гарантирует:
- Конфиденциальность - гарантия того, что ни одна сторона, кроме предполагаемого получателя, не сможет получить доступ к содержимому сообщения
- Целостность - гарантия того, что сообщение не было изменено при передаче
- Аутентификация - гарантия того, что личность отправителя может быть проверена
- Неотрицание - гарантия того, что отправитель не сможет обоснованно отрицать факт отправки сообщения
Как генерировать PGP ключи
Как я уже упоминал, существует бесплатная библиотека и ПО, которые реализуют PGP протокол - GnuPG. Есть несколько способов как ими пользоваться, я предпочитаю использовать терминал. Команды, приведенные ниже, подходят для операционных систем MacOS и Linux, а также, скорее всего, Linux подсистемы в Windows - WSL.
Если работать с PGP в терминале вам некомфортно, я советую посмотреть в сторону инструкций Surveillance Self-Defense от Electronic Frontier Foundation. Они доступны в том числе на русском языке.
На MacOS GnuPG может быть установлен через Homebrew.
На Linux используя стандартные средства, например APT в Debian/Ubuntu.
После установки можно приступать к генерации ключей. Для этого мы будем использовать команду gpg
и параметр --full-generate-key
. После ввода команды нам будут заданы вопросы с настройками, на основании ответов на которые генерируются ключи.
Сначала выбираем тип ключа, который хотим создать. Можно нажать Enter
чтобы выбрать тип по умолчанию, на MacOS это ECC (sign and encrypt)
. Если вы не видите такой тип в списке, а по умолчанию предлагается RSA, воспользуйтесь параметром --expert
, чтобы увидеть больше опций.
Дальше нам предлагается выбрать эллептическую кривую. Берем Curve 25519
и переходим к сроку действия. Можно создать ключи с ограниченным сроком действия, это хорошая, но продвинутая практика, придется перегенерировать ключи до даты истечения, чтобы начать работать с PGP это не нужно, поэтому выбираем key does not expire
.
Для RSA будет предложен выбор размера, если вы, по какой-то причине не можете использовать ECC, а доступен только RSA, я бы рекомендовал как минимум 4096.
Дальше нам нужно будет заполнить идентификационные данные, такие как имя и email. В поле комментарий можно ввести любую информацию.
На следующем шаге нужно будет дважды ввести пароль для ключа, тут как всегда, он должен быть достаточно сложным, но если вы его забудете/потеряете, то уже никогда не сможете пользоваться приватным ключом из этой пары. Сгенерировать хороший случайный пароль можно в специальном Telegram боте.
Вот и все! Теперь у вас есть приватный и публичный ключи, которые можно использовать для шифрования и подписывания. Чтобы просмотреть список доступных публичный ключей, можно использовать команду:
А чтобы посмотреть доступные приватные ключи, команду:
Используйте параметр --fingerprint
чтобы отобразить отпечатки ключей. Это длинная строка из 10 блоков с 4 цифрами и буквами в каждом.
Чтобы поделиться вашим публичным ключом его нужно экспортировать в текстовый файл. Для этого можно воспользоваться следущей командой, заменив {firstName}
и {secondName}
на те, что были указаны при генерации ключей. Вместо имени можно также использовать email.
Как импортировать публичный ключ и зашифровать им сообщение
Представим, что кто-то хочет отправить мне сообщение зашифровав его моим публичным ключом. Для этого ему НЕ нужно иметь собственные ключи, но необходимо иметь установленной GnuPG.
Первым делом нужно скачать мой публичный ключ со специальной страницы. Это можно сделать через браузер или в том же терминале, с помощью команды:
Теперь его нужно импортировать, это позволяет сделать параметр --import
с указанием файла ключа.
Теперь публичный ключ отображается в списке и следующим шагом стоит сравнить его отпечаток с тем, что указан на сайте и в соц. сетях, чтобы быть уверенным что это правильный ключ.
Чтобы зашифровать короткое сообщение прямо в терминале, можно воспользоваться следующей командой:
Параметр --encrypt
указывает на то, что мы хотим сделать шифрование. Параметр --armor
позволяет сгенерировать текст, который можно легко скопировать, а не бинарный формат по умолчанию. Параметр -r
или --recipient
указывает на получателя сообщения, именно по нему будет выполнен поиск публичного ключа для использования.
Эта команда, скорее всего покажет предупреждение, что нет гарантии, что ключ принадлежит этому человеку и спросит нужно ли продолжать. Если ответить положительно, вы увидите текст начинающий c -----BEGIN PGP MESSAGE-----
и заканчивающийся -----END PGP MESSAGE-----
. Это и есть зашифрованное сообщение. Его можно безопасно отправить любым каналом связи и только я смогу его расшифровать.
Если вы уверены в каком-то конкретном ключе, вы можете изменить его уровень доверия в GnuPG и тогда предупреждения не будет. Для этого можно воспользоваться параметром --edit-key
.
Далее вам будет предложен выбор уровня доверия.
После подтверждения выбора можно выйти из редактирования ключа командой quit
.
Дополнительные материалы
Примеры критики PGP:
Продвинутые техники:
- Operational PGP
- Using OpenPGP subkeys in Debian development
- signify: Securing OpenBSD From Us To You
Альтернативные инструменты:
#Security #TechAndDev