Приветствую.
Интересует возможность использования (совершенной)прямой секретности с GnuPG(и другими реализациями PGP). GPG удобен своей гибкостью(пусть и требует от пользователя определённого опыта) и тем, что позволяет легко превращать любые данные в base64-шифротекст, предоставляя возможность обмениваться не только текстом, но и медиафайлами и целыми архивами.
Однако асимметричные криптосистемы, поддерживаемые GnuPG, статичны(ECC тоже) и работают только по «классической» схеме с использованием долговременных ключей. Использование постоянных ключей для шифрования подразумевает возможность восстановить переписку при компрометации единственного секретного ключа(дешифруются все сообщения одной стороны, легко предполагается содержание шифротекстов другой), что не позволяет обеспечить ни прямую, ни обратную секретности. Более того, единственный доступный способ аутентификации(ЭЦП) не предполагает отрицаемости сообщений, что ставит под угрозу обе стороны.
Должен уточнить, это вовсе не праздный теоретический интерес, на данный момент завершаются работы над системой обмена сообщениями через Tor, шифрование сообщений в которой возложено целиком на пользователя(защиту от стороннего наблюдателя, конечно, обеспечивает и Tor, но защиту от злого админа(меня) обеспечивают только сами пользователи). Соответственно, теоретические и практические наработки пойдут в руководство пользователя. Ссылку на систему я вам и всем желающим дам чуть позже, как только будет завершено оформление и наполнение сайта(сама система полностью готова).
Какой вариант я рассматриваю сейчас?
Рассмотрим ситуацию с двумя участниками обмена: Алисой(адресант, инициатор) и Бобом(адресат). Пошагово это выглядит так(предполагается использование RSA, но это работает с любым асимметричным алгоритмом, в т.ч. «постквантовым»):
- Алиса и Боб генерируют две пары долговременных ключей(одну каждый) и обмениваются открытыми ключами друг с другом.
- Алиса дополнительно создаёт одноразовую пару ключей.
- Алиса отправляет свой одноразовый открытый ключ Бобу, предварительно зашифровав его долговременным открытым ключом Боба и подписав своим постоянным секретным ключом.
- Боб, удостоверившись в аутентичности подписи, отправляет временный секрет(длинную псевдослучайную последовательность символов), его «срок жизни»(количество сообщений и срок годности) и предпочтительную схему симметричного шифрования(AES, Twofish, Serpent и т.п. с длиной ключа, прим AES-128.) Алисе, предварительно зашифровав сообщение одноразовым открытым ключом Алисы и подписав своим постоянным секретным ключом. На данном этапе аутентификация завершена.
- Алиса, уничтожив временную пару ключей, отправляет тестовое сообщение, зашифрованное уже общим секретом, благодаря чему обеспечивается аутентичность всех сообщений с тем же секретом, повышается(на порядки) скорость работы и стойкость шифрования(в разы).
- Полученный секрет используется до окончания его «срока жизни», после чего операция повторяется, начиная со второго шага.
При использовании такого подхода компрометация долговременных ключей раскроет только метаданные(когда и с кем устанавливалось соединение), но не позволит дешифровать основную информацию. Чтобы усложнить анализ содержимого по размеру криптограммы, каждое сообщение дополняется случайным количеством случайных данных в base64. Например так:
#!/usr/bin/env bash
randexp=$(cat /dev/urandom | tr -dc '1-3' | head -c1)
randbyte=$(cat /dev/urandom | tr -dc '0-9' | head -c$randexp)
cat /dev/urandom | head -c$randbyte | base64
Что насчёт анонимных сообщений? Всё просто - используется открытый ключ одной из сторон, но адресант не подписывает сообщение. Известен получатель, но не отправитель. А первоначальный обмен открытыми ключами можно произвести, например, с помощью OnionShare(«Trust» в Web of Trust, КМК, доверия не заслуживает).
Коллега предложил использовать долговременные ключи только для подписи, а ключи для шифрования запрашивать по необходимости, подписывая запрос. На мой взгляд такой подход слабее, а площадь атаки много больше.
На первый взгляд всё красиво, не так ли? Да и всю эту «рутину»(кроме первого шага) можно автоматизировать одним коротким исполняемым файлом.
Тем не менее, какие уязвимости есть у такого подхода? Интересует ваше мнение.
И ещё, GPG при работе с блочными шифрами использует режим CFB. Выглядит неплохо, но распространено утверждение, что CTR для подобных целей подходит намного больше. Так ли это?
Как бы то ни было, заранее спасибо за помощь.