Next: , Previous: , Up: Articles  


Libre/OpenPGP vs OpenSSH/age

Я использую GnuPG (реализацию OpenPGP и LibrePGP) каждый день на протяжении более чем десяти лет. У меня накопилось почти две сотни публичных ключей разных людей с которыми я общался и общаюсь по почте. Почти три сотни публичных ключей для проверки дистрибутивов операционных систем и архивов исходного кода программ. И это не считая более чем полутора тысяч публичных ключей из ключниц GNU, Linux, Debian, FreeBSD и других проектов. Я был постоянным популяризатором OpenPGP экосистемы и рекомендовал её использовать для массы задач, возникающих даже в банальных домашних условиях. Но за последние пару лет я ощутимо поменял своё мнение насчёт её рекомендации. Перестал всё это использовать почти везде где можно.

Какие задачи PGP может решать?

Во-первых, конечно же возможность зашифровать файл, чтобы безопасно передать его другому человеку. Во-вторых, подписать его, чтобы получатель мог убедиться в том, что на другом конце, как минимум, тот же самый отправитель что был и раньше. Соответственно, в обоих случаях нужно знать публичный ключ получателя (для шифрования) и отправителя (для проверки подписи).

В 99% именно эти две простые задачи и нужно решать людям. *PGP же, в том числе и его распространённейшая реализация GnuPG, умеет много чего другого: подключи, разные идентификаторы пользователя, предпочтения в выборе алгоритмов и ключевых серверов, отзыв UID-ов и ключей, ограничение их времени жизни, сертификация (подпись сторонних публичных ключей) разными уровнями доверия и политиками, выбор доверенного "отзывателя" и многое другое. Ко всему этому размашистая гибкая система управления доверием, поддержка Web-of-Trust и TOFU (Trust-On-First-Use) моделей с сохранением на диске от кого, когда и какие ключи/подписи мы видели. Разные форматы сообщений и ключей (detached signature, ASCII, MIME, PKCS#12, ...). Интеграция с электронной почтой и MIME. Работа с ключевыми серверами по HKP, WKD, DANE, LDAP протоколам. Работа со смарт-картами. И ко всему этому, ещё и работа с X.509 сертификатами и S/MIME экосистемой.

Каждая из этих возможностей требует колоссального количества программного кода и усложнения формата ключей и сообщений. А много кода всегда означает большую поверхность для атаки, больше возможностей что что-то пойдёт не так, будут выявляться и эксплуатироваться уязвимости. Если в 99% случаев человеку нужно "просто дайте мне зашифровать файл, указав публичный ключ получателя", то зачем вся эта безумная сложность?

И раз задача шифрования/подписи кажется такой простой, то не глупо ли рекомендовать *PGP? Много людей в блогах рекомендуют "просто использовать OpenSSL" и выполнять из командной строки что-то типа: openssl aes-256-cbc .... Действительно, файл будет зашифрован, но отнюдь не безопасным образом, как минимум например из-за отсутствия проверки целостности передачи (нет MAC). А как передать этот симметричный ключ другой стороне? И вновь можно увидеть множество предложений одно хуже другого. Люди далёкие от темы прикладной криптографии, зачастую просто не смогут грамотно использовать эти низкоуровневые инструменты и возникнет удручающая иллюзия безопасности.

Иллюзия страшна тем, что человек уже не способен адекватно оценивать риски – он уверен что безопасно передаёт/подписывает/whatever файл, хотя на самом деле он запросто не более защищён чем полностью открытая передача. Если человек без иллюзий понимает, что у него нет безопасного способа передать данные (например нет нужного ПО на компьютере), то он будет ждать подходящего момента, специалиста, программы, пригодного канала связи (личная встреча например). С иллюзией же он легко совершит непоправимое.

И рекомендация "просто используйте GnuPG" не из серии "просто используйте наш коммерческий продукт XXX, который лучше всех конкурентов, потому что мы так сказали", а потому что с GnuPG гораздо сложнее напортачить с такими, казалось бы, относительно простыми задачами. Он написан людьми которые понимают в прикладной криптографии больше чем многие из нас. Конкретно GnuPG является полностью свободным ПО, с относительно неплохим качеством кода и, в целом, небольшой историей фатальных косяков и ошибок, в отличии от того же OpenSSL или, тем более, коммерческих проприетарных закрытых решений. И именно всё это перевешивает возможность пользователю легко ошибиться в неграмотном использовании (слепом копировании безграмотных примеров из Интернета) шифрования/подписей.

Чем недовольны в PGP?

За последние лет пять, много статей появилось с критикой PGP.

Преобладающая часть из них критикует то, что в нём нет свойства совершенной прямой секретности – мол компрометация долгоживущего ключа скомпрометирует и ранее перехваченные сообщения. И предлагают использовать интерактивные online протоколы. Я считал и считаю это безграмотнейшей глупостью, сравниванием яблок и апельсинов. Мы про однократную передачу данных, а они про множественные приёмо-передачи. Для ЭЦП (электронных подписей) интерактивные протоколы никоим боком. Для хранения зашифрованных данных – очевидно, тоже ни о каких интерактивных протоколах речи не может идти. Похоже, что все эти люди пытаются использовать PGP для чужеродных ему задач?

Другая часть критикует за недочёты и косяки проявляющиеся в других программах, как например в EFAIL. Тут проблема в разработчиках-интеграторов, и косвенно в сложности *PGP стандартов, MIME и реализаций. Кто-то критикует использование не лучшего метода дополнения RSA PKCS#1.5, когда ведь есть куда более безопасные алгоритмы типа OAEP и PSS. Что тоже глупо, ибо в задачах на которые ориентирован *PGP – это не создаёт практических проблем. Может быть, опять же, кто-то пытается использовать PGP для совершенно несвойственных ему задач? Есть критика использования не очень современных алгоритмов: мол ElGamal, RSA, не AEAD-шифры, и т.д.. Как давно все эти критики обновляли свою OpenPGP реализацию? Это уже много лет не актуально для GnuPG.

Всё вышеназванное, по моему, высосано из пальца и притянуто за уши для несвойственных *PGP задач. Но чаще других встречается критика сложности его интерфейса и вообще понимания что пользователю надо делать для просто подписи и шифрования файла. Действительно, тьма опций командной строки, куча команд, разные демоны, сокеты, конфигурационные файлы... От этого не уйти, если учесть как много всего GnuPG умеет.

И я, считая что большая части подобной критики безграмотна и не оправдана, продолжал рекомендовать GnuPG, подчёркивая, что нужно узнать только несколько его опций и команд для практического применения. О том же Web-of-Trust и ключевых серверах (а также DANE, WKD, whatever) совершенно не нужно думать и вспоминать, если вам достаточно обменяться с человеком ключами и посылать шифрованные/подписанные файлы.

А альтернативы нет что ли?

Неужели нет альтернативы навороченному OpenPGP и GnuPG? По сути, действительно, толком не было. Долгое время GnuPG из коробки шёл во многих Unix-дистрибутивах. То есть, это решение сразу же присутствовало на каждом компьютере (под управлением свободной ОС конечно же, ведь какая может идти речь про безопасность/шифрование/криптографию, если вы не управляете своим компьютером?) и поэтому не нужно было терзаться вопросом выбора.

Но стандарт OpenPGP развивался, появлялся новый функционал. GnuPG уже не одна программа, а стал состоять из нескольких связанных между собой демонов, со сторонними зависимыми библиотеками. Относительно простая программа стала прилично громоздкой и дистрибутивы перестали включать современные и актуальные версии GnuPG, в которых были и важные исправления безопасности, оставляя старую версию только для проверки подписей. Некоторые вообще избавлялись от сложной экосистемы *PGP и придумали собственные минималистичные решения для подписи пакетов/дистрибутивов.

GnuPG перестал быть программой де-факто идущей из коробки. Вскоре появились и другие реализации OpenPGP, а также возникли колоссальные разногласия и отсутствие общего знаменателя в обсуждениях доработок и наработок в OpenPGP стандарте. Всё это происходило в течении многих лет. Но уже сейчас дошло до того, что многие серверы ключей уже не очень совместимым образом работают с GnuPG. А GnuPG, в свою очередь, вовсю использует ещё официально не вошедшие в OpenPGP стандарт наработки.

Недавно из-за всего этого появилось ответвление от OpenPGP в виде LibrePGP. Так, например, автор GnuPG принципиально не готов никоим образом мириться с предложением включить опциональную возможность использования GCM AEAD-режима шифрования, ссылаясь на то, что уже имеется и вовсю используется OCB. Лично я солидарен с этим: OCB и по производительности (не учитываем возможности аппаратного ускорения) и по порогу и уровню безопасности вне конкуренции лучше чем GCM, так что права на существование GCM, созданного как костыль из-за (когда-то) патентованности OCB, просто нет. Разработчики же других решений, на JavaScript (удивительно, но как это может вообще присутствовать в мире криптографии?) и на Rust – всё равно упорно хотят формального разрешения для их применения. Судя по всему, LibrePGP и OpenPGP так и будут существовать параллельно друг с другом, а GnuPG вряд ли будет поддерживать новую версию OpenPGP. И даже если и появятся fork-и сочетающие оба стандарта, то лично я принципиально не стал бы использовать то, где добавили GCM. В итоге, ни о какой широкой совместимости уже не приходится говорить, если только не использовать архаичный прошлый общий знаменатель стандарта.

А сделать альтернативу?

Написать OpenPGP или LibrePGP реализацию с нуля, но чтобы была достаточна мала, удобна и пригодна вновь для в поставки дистрибутивов – нетривиальная задача, учитывая громоздкость этих и сопутствующих стандартов. Но надо ли это всё? Возвращаемся к оригинальным двум задачам: зашифровать и/или подписать файл на асимметричных ключевых парах. Неужели так сложно написать простейшую утилиту для этого, чтобы не сведущий в прикладной криптографии пользователь мог бы её безопасно без иллюзий использовать?

Вообще то любой программист, кто занимался прикладной криптографией, может придумать и написать подобное за пару часов без преувеличений. Проблема как всегда в том, чтобы преобладающее большинство выбрало бы что-то одно (де-факто), а не появлялся бы ещё один зоопарк несовместимых между собой решений, как это изо дня в день происходит в мире свободного ПО.

OpenBSD сделала простейшую утилиту signify, которая ничего не умеет делать, кроме как подписывать и проверять подпись файла. С тех пор, их дистрибутивы ею и подписываются. Затем некую популярность получила утилита minisign, частично совместимая с signify. Вскоре в OpenSSH команду ssh-keygen добавили возможность подписывать и проверять произвольные файлы. Смотрите насколько простой формат такой подписи:

byte[6]   MAGIC_PREAMBLE
uint32    SIG_VERSION
string    publickey
string    namespace
string    reserved
string    hash_algorithm
string    signature

Учитывая, что зачастую OpenSSH из коробки есть на компьютере пользователя, то значит у него уже есть крайне простое, но достаточное для подписей решение. В Git тоже добавили поддержку OpenSSH подписей, наравне с OpenPGP/GnuPG. Плюс ssh-keygen команда активно намекает пользователю на то, чтобы он не забывал про файл с доверенными (pinned) публичными ключами, задумывался об управлении доверием.

Явное шифрование файлов же используется в обычной повседневной жизни сильно реже чем создание и проверка подписей. Так как безопасно передать файл можно через шифрованный канал связи (VPN, SSH, TLS, ...). Но, пожалуй, лучшим кандидатом на роль программы для шифрования файлов является age. Автор очень хорошо смыслит в криптографии, есть реализации на разных языках программирования. Поддерживает несколько получателей. Вместо публичного ключа можно использовать scrypt-усиленную парольную фразу. Формат заголовка крайне прост, например:

age-encryption.org/v1
-> X25519 1/ZMKbIr4hrWfTVn0sXeD4exrgZYC80k7Ik2pdNC+mQ
HUJTIAjnmAqj/i9HGyx4njRq8Ak7I23PMVCRTZRCQmQ
-> X25519 DauD6lc8mMzqx0y1Xe7A891Lgi9d6GbqDVLb0uqeACc
XvDCd1vr0mV9dqiTIrQroFRkH0lnPHSLUW/ShZ5z0Nk
--- AqIyI4RcI1agwP1wQoO5y0E8leySl40asEGV8obo/uc

Видна волшебная строчка, версия, тип получателя (X25519 или scrypt), публичный ключ или аргументы для scrypt, и заканчивается всё это MAC-ом заголовка. Выработка ключей на основе HKDF-SHA256. А дальше ChaCha20-Poly1305 зашифрованные 64KiB блоки данных. Вот и всё! Как шифруется приватный ключ age? Явно – никак, но кто мешает его зашифровать самим же age-ом на scrypt-усиленной парольной фразе?

Я очень ценю простоту. Любой может придумать сложное решение. А сделать что-то лёгкое и простое, но отлично выполняющее задачу – сложно. Я бы использовал иной формат заголовка, немного другие алгоритмы выработки ключей, но всё это по сути мелочи, вкусовщина и age остаётся отличным решением для шифрования, так что не надо городить свой формат. Реализовать его поддержку с нуля – дело нескольких часов на многих языках программирования.

Замена ли это *PGP?

Ни в коем случае. Только пары несвязанных между собой задач. age сам по себе никак не аутентифицирует отправителя. А подписанный (ssh-keygen) зашифрованный (age) файл не означает что шифротекст действительно создан подписантом. Необходимо применять, так называемый, "signcryption". Отдельно применённые "sign" и "encryption" им не являются. Но стоит заметить, что и S/MIME, и PEM, и PKCS#7 с CMS, и PGP/OpenPGP когда-то, и XML-Signature с XML-Encryption – все имели точно такую же проблему с наивной конструкцией из подписи и шифрования. Это не оправдывает их криптографическую бездарность, но всё же говорит о том, что для большинства применений подобная наивная конструкция не столь фатальна.

OpenSSH+age не имеют ни Web-of-Trust, ни PKI, на отзыва ключей, ни времени их жизни. Но давайте будем честны – а оно надо для этих двух простых задач? Речь не про архивные юридически сильные документы, содержащие ещё и временные штампы со сложными цепочками доверия сертификатов – подобных монстров многие ИТ-люди вообще могут за всю свою жизнь не встретить. Но уж подписать или зашифровать файлик то можно без всего этого геморроя? Я участвовал в десятке PGP keysigning party, на всех работах был обмен публичными ключами – но Web-of-Trust, как таковой, возможно от силы пару раз использовался. Ничего плохого в отзывах и явных ограничениях времени жизни ключей нет. Эта не плохая практика. Но если на одной чаше весов у нас в стократ более сложная громоздкая система/код, а на другой всего-лишь отсутствие отзыва ключей, то безопасность зачастую будет на стороне простоты. Как часто действительно компрометируется ключ и он при этом честно отзывается, все это каким-то образом честно получают и учитывают в своих цепочках доверия? А вот критичные уязвимости из-за переусложнённых программ, форматов и протоколов находятся регулярно.

Так ли плохи решения с жёстко вшитым единственным алгоритмом шифрования/подписи/DH? Да даже если взять древнее решение с 3DES+HMAC-MD5 или оригинальный PGP с IDEA, где никакой из алгоритмов не применяется сейчас, то вы всё равно их не "взломаете", ибо запаса прочности 3DES более чем достаточно, а MD5 в составе HMAC не является небезопасным.

Salsa20/ChaCha20 шифры внимания не намного меньше за десятилетия к себе привлекали чем AES, они очень хорошо исследованы. И кроме производительности и простоты имеют и очень высокий порог безопасности. Аппаратно ускоренный AES-GCM/OCB зачастую конечно быстрее ChaCha20-Poly1305, но речь в лучшем случае всего о паре десятков процентов разницы в производительности на amd64 системе. Мизерная цена за гораздо более простой и безопасный код.

*25519 асимметричный алгоритм, на котором и OpenSSH и age (и WireGuard, в котором тоже нет выбора алгоритмов) выполняют свои операции и проще, и быстрее, и безопаснее (особенно, если учесть что ему не требуется генератор псевдослучайных чисел). Опять же, никаких сомнений или нареканий к нему не возникает у криптографов.

Когда мы в последний раз видели чтобы ломали какой-то формат или протокол, потому что в нём был уязвимый шифр? RC4, который нигде и не использовался серьёзно, если были привлечены криптографы? А вот если в протоколе или формате можно согласовывать/выбирать эти алгоритмы, то downgrade атак или уязвимостей в ASN.1 парсерах (из-за вынужденно сложных форматов) мы видели тьму. Решения с моно-алгоритмами просто не подвержены этим атакам.

Email и IM

*PGP часто используется для защиты электронной почты. И тут альтернатив ему нет. S/MIME и PEM решения – ещё более громоздкие и менее гибкие.

К сожалению, с открытыми и свободными федеративными (или распределёнными) средствами общения у нас всё плохо. Придумать онное и вовлечь в него десяток человек – проще пареной репы. А вот вовлечь критическую массу людей уже не выходит. Email пока остаётся единственным распространённым работающим федеративным решением, где вы можете поднять свой собственный сервер и общаться с тысячами других серверов, имея проблемы только некоторыми крупными участниками (типа Google, Microsoft) не заинтересованными в поддержке существования email.

Какие ещё открытые и свободные протоколы передачи сообщений можно бы было назвать, которые имели хоть какое-то хождение? IRC не федеративен. XMPP (как наверное и многие другие менее распространённые) из-за тотального бездумного "криптобесия" тоже уже не может объединяться в федерацию. Сисопы XMPP часто стали форсировать не только использование TLS для связи между серверами (будем считать, что это в целом не плохо), но и обязательную успешную проверку сертификатов напротив локальных цепочек доверия. С какой стати предполагается, что у людей вообще будут общие якоря доверия? Кто-то использует якоря предложенные компаниями США. Кто-то использует CACert.org. Кто-то российскую Минцифру. Проверить сертификат уже не выйдет, TLS соединение не будет установлено, федерации нет. А у конечных пользователей, даже при неаутентифицированных соединениях между серверами, остаётся возможность использовать end-to-end защиту в виде OMEMO или даже архаичного OTR. Но при отсутствии федерации, у них никакой связи не остаётся. Пытаться считать какой-нибудь Let’s Encrypt общей точкой доверия? Инцидент с jabber.ru вроде бы отчётливо показал, что domain validated сертификация не защищает от возможности проводить MitM провайдерам и ЦОДам.

Matrix? Спецификация протокола имеется, но покажите мне вменяемый простой терминальный клиент для него? Для XMPP их десятки. Для протоколов и форматов нужны работающие реализации, выбор программ. Прискорбно когда организации даже для внутреннего использования поднимают какой-нибудь Mattermost, у которого вообще нет толком никаких клиентов для ПК, кроме автоматически скачиваемой и запускаемой программы на JavaScript. О какой адекватности этого решения и безопасности подобной экосистемы может идти речь? Программисту нужно средство пригодное для дискуссий и эффективной работы с нитями сообщений, а не очередной чатик.

Tox? Его разработчики, к сожалению, не очень понимают в криптографии, да и распределённое DHT решение имеет незавидный quality-of-service: временами могут проходить минуты, прежде чем соседние компьютеры из одной сети отошлют таки друг другу сообщение, что неизбежно в распределённых решениях.

Удручает что у нас уже целые поколения никогда не видели и не использовали десятилетиями развиваемые непревзойдённо удобнейшие почтовые инструменты (правда, требующие нехилый порог входа чтобы разобраться со всеми этими MTA, MDA, MUA взаимосвязями), не подозревают о существовании сетикета и их регулярно приходится отправлять читать сайты из серии "не привет" и объяснять как надо грамотно задавать технические вопросы. Особенно во времена COVID было заметно, как многие (большинство) люди просто не умеют хоть сколько то эффективно общаться по профессиональным вопросам на удалённой работе.

Резюмируя применимость этих утилит

Для 99% применений у пользователей, ssh-keygen и age будут более чем удовлетворительны. И куда безопаснее из-за много порядков меньшего количества кода и размера поверхности возможных атак, плюс ощутимого нивелирования человеческого фактора из-за простоты этих программ. Форматы подписи и шифрования в них настолько тривиальны, что их реализация займёт считанные часы (предполагаем что уже имеются библиотеки распространённых криптографических примитивов). ssh-keygen, как правило, уже из коробки имеется в Unix дистрибутивах, а age компактен, минималистичен и его реализацию можно собрать хоть на встраиваемой системе. Простота – это надёжность, безопасность и удобство.


Next: Сравнение JPEG XL, Previous: Vo(IP) Really Simple: Пишем простое VoIP решение, Up: Articles