Я строю системы уже 25 лет, и мне нравится создавать вещи, которые намеренно спроектированы и операционно легки, несущие только столько вектора, сколько оправдывает свою тяжесть.
В таком подходе минимизация того, что я храню из данных пользователя, всегда имела смысл для меня, по причинам, выходящим за рамки очевидного. Суверенитет их данных важен. Под этим скрывается что-то проще: вещи принадлежат там, где они должны быть. Большая часть того, что я строю, это обработка, и архитектура обработки не имеет смысла функционировать как что-то другое. Хранение записи, которую никогда не нужно, является вектором, который ничего не приносит. Относиться к этому как к оптимизации, а не как к упражнению по соблюдению требований, делает дизайн честным — и система, построенная таким образом, обычно находится в хорошем положении с регуляцией сама по себе, потому что осталось очень мало, что регулировать.
Поэтому, когда объявление Mary Camacho попало в мой поток на X, я прочитал её архитектуру так же, как читаю свою собственную. Она опубликовала ядро в публичный реестр под лицензией Creative Commons, на уровне детализации, необходимом инженеру для его восстановления, и была прямолинейна относительно предшествующего искусства, на котором она основана.
Прорабатывая последовательность, я разместил противостоящую сущность внутри сервера и следил, к чему она может добраться. Она могла обогнать работника.
Почти вся работа, которая последовала, происходила как голосовой разговор — через 30 голосовые заметки, думая вслух и тестируя обеспокоенность с разных углов, пока она не выдержала или не распалась.

Что я заметил: устройство шифрует для того, кто первым записывает запись претензии

Раскрытие указывает порядок операций напрямую. Работник претендует на работу и публикует свой ключ, и только после этого устройство шифрует:
  1. Работник → координация: опрашивает и претендует на работу (запись-один раз, первый-побеждает), публикуя открытый ключ работника.
  2. Устройство ← координация: опрашивает, получает открытый ключ работника, выводит общий секрет, шифрует полезную нагрузку.
— §2.1, Поток данных (по работе)
Сторона устройства в этом соглашении указана с такой же точностью:
Устройство, узнав открытый ключ работника, выполняет собственный обмен X25519 и инкапсуляцию ML-KEM против ключа работника, создавая свой собственный открытый вклад (X25519 открытый ключ ‖ ML-KEM шифротекст) и общий секрет.
— §4.2, Связывание с жизненным циклом работника
При получении. На протяжении 19 страниц нет подписи над эфемерным открытым ключом работника, нет сертификата, нет аттестации, которую устройство оценивает, и нет предварительно обмененного секрета. Отсутствие намеренно и представлено как сильная сторона: модель блокирует расшифровку без документа аттестации, цитаты TPM или артефакта измеренного загрузки, и она не хранит предварительно предоставленный секрет работника.
Поэтому устройство шифрует свою полезную нагрузку для любого открытого ключа, который находится в записи претензии, без возможности отличить законный ключ работника от любого другого. Любой, кто первым напишет претензию, становится тем, кому устройство шифрует, и доверенная полезная нагрузка расшифровывается у него.
Diagram source
flowchart TB
    subgraph BEFORE["До: как опубликовано"]
        direction LR
        A2{"Кто заявляет первым?"} -->|Реальный работник| A3["Подлинный ключ"]
        A2 -->|Любой другой писатель| A4["Ключ злоумышленника"]
        A3 --> A5["Устройство шифрует его"]
        A4 --> A5
        A5 --> A6["Хозяин ключа может читать"]
    end
    subgraph AFTER["После: подписанный ключ"]
        direction LR
        B2{"Подпись действительна?"} -->|Да| B3["Подтверждённый ключ работника"]
        B2 -->|Нет| B4["Отклонить, повторить"]
        B3 --> B5["Только настоящий работник читает"]
    end
    A6 ~~~ B2
Серьёзность исходит от того, что модель несёт. Эта архитектура существует, чтобы хранить ровно те данные, которые люди меньше всего хотят, чтобы их читали, и она успешно решает более сложную половину этой задачи: завершённая работа не может быть расшифрована никем, включая оператора. Разрыв находится в одном шаге, когда устройство должно установить, с кем оно разговаривает.

Криптография надёжна, а ввод не аутентифицирован

Злоумышленник ничего не ломает. X25519 и ML-KEM-768 работают точно так, как указано. Злоумышленник предоставляет ключ и становится законным участником соглашения.
Это аутентифицированное соглашение ключей, и его режим отказа — самая старая результат в области. Обычный Diffie-Hellman не аутентифицирует никого и падает к участнику, который заменяет свой собственный открытый ключ. Механизмы инкапсуляции ключей наследуют это свойство, поэтому RFC 9180 размещает аутентичность открытого ключа получателя вне его собственного диапазона и предполагает, что окружающее приложение устанавливает её через сертификаты, каталог ключей или внеканальное подтверждение. Эта модель — это окружающее приложение, а канал, который оно использует для распространения ключа получателя, является компонентом, который его собственная модель доверия помечает ненадёжным.
Раскрытие предвидит соседний атаку и закрывает её:
Заявка является запись-один раз/первый выигрывает, поэтому более поздний работник не может захватить обмен ключами работы.
— §6, Реализация примера
Это рассуждение надёжно, и механизм делает то, что говорит. Он охватывает один из двух симметричных случаев.
УгрозаОбрабатывается однократным заявлением
Второй работник перезаписывает существующее заявлениеДа — запись отклоняется
Неавторизованная сторона записывает заявление первойНет — первая запись выигрывает
First-wins — это гонка. Правило гарантирует, что победитель сохраняет работу и ничего не говорит о том, кто победитель.
Еще одно утверждение стоит процитировать, потому что вывод противоречит ему:
Ни один посредник (шлюз, координация, хранение, монитор) никогда не хранит достаточно ключевого материала, чтобы вывести любой из секретов. Угроза, которая компрометирует координацию или хранение, получает только непрозрачные блобы и открытые ключи.
— §4.3, Независимые ключи по направлению
Первое предложение точное. Второе описывает злоумышленника, который читает. Угроза, которая пишет, размещает выбранный открытый ключ в записи заявления до того, как устройство опросит, и получение законного секрета становится ненужным для стороны, которая может устроить себя в качестве контрагента. Кто управляет содержимым этой записи, тот управляет тем, кто может читать полезную нагрузку, что делает слой координации доверенным компонентом для конфиденциальности — единственная вещь, которую §3 говорит, что никакой компонент, кроме устройства и работника, никогда не должен быть.
Честное ограничение на заявление: это не означает, что кто-либо в открытом интернете может читать эти данные сегодня. В реальном развертывании возможность писать заявления находится за облачной сетью и учетными данными, а раскрытие описывает аутентифицирующий шлюз на пути устройства. Точная проблема в том, что конфиденциальность теперь зависит от того периметра, в то время как центральное обещание архитектуры состоит в том, что она сохраняется без доверия компонентам между устройством и работником.

Две проектные особенности усиливают последствия

Результаты возвращаются к устройству под вторым соглашением, которое тот же злоумышленник посредничает, поэтому перехваченная работа завершается и выглядит обычной с точки зрения пользователя.
Намеренное отсутствие долговременного журнала работы и результатов — то же отсутствие, которое создаёт отсутствие надёжного хранения и уменьшает регуляторную поверхность — убирает большую часть того, что позже использовал бы следователь для восстановления того, какие работы были затронуты. Записи о координации истекают примерно через час. Свойство, которое защищает данные в обычном случае, истончает судебно-выяснительный протокол в противоборствующем случае.

Пробел — это тень, отбрасываемая лучшим решением модели

Архитектура разделяет данные, которые оператор может законно хранить, от данных, которые он никогда не должен хранить. Контактные данные — это кто человек и как с ним связаться. Конфиденциальные данные — это то, что они раскрывают о себе. Обычные системы сохраняют оба типа в одной базе данных, что превращает таблицу аккаунтов в запись чьей-то личной жизни. Структурный ответ — одна строка: хранить контакт, не иметь возможности хранить конфиденциальные данные.
Удаление центрального оркестратора напрямую служит этой цели. Компонент, который назначает работы работникам, обязательно узнаёт, кто делает что, и это знание является точным активом, который модель отказывается хранить. Удаление его также убрало компонент, который обычно подтверждал бы личность работника, и каждый оставшийся путь к аутентификации работника был независимо отклонён, каждый по обоснованной причине.
Результатом является дизайн, который рассматривает хранение с реальной строгостью и применяет рассуждения о хранении в той точке, где форма проблемы — аутентификация. Модель доверия спрашивает, что каждый компонент хранит, и отвечает правильно. Вопрос, который нужен, — это что каждый компонент может заменить. Это две независимые проблемы доверия, и решение одной из них никогда не решало другую.

Подпись над эфемерным публичным ключом рабочего закрывает его

Работник генерирует свою эфемерную пару ключей при запуске точно так же, как сейчас. Прежде чем этот ключ публикуется в заявлении, он подписывается долгосрочным ключом оператора, публичная часть которого поставляется с приложением. Устройство проверяет подпись перед тем, как производить что‑либо, и отказывается от неподписанного или недействительного ключа. Восстановление уже указано, поскольку клиент‑управляемый повторный запрос с новой задачей и новым соглашением ключей является стандартным путем отказа модели.
Решающее свойство: подписочный ключ ничего не расшифровывает. Компрометация подписочного ключа оператора позволяет имитировать рабочего вперёд и не даёт возможности прочитать ни одну завершённую задачу, потому что ключи каждой задачи были уничтожены вместе с их рабочими. Не‑хранение, пустой хранилище ключей и невозможность ретроспективной расшифровки остаются целыми. Это то, что делает завершением дизайна.
Подписывающий остаётся вне процесса становления оркестратором, который дизайн удалил. Ему нужно только подтвердить, что данный эфемерный публичный ключ принадлежит рабочему, запущенному оператором, и ему никогда не нужно знать, какую задачу этот рабочий заявит. Существующий монитор — естественное место: он уже развертывает и собирает рабочих, не хранит пользовательские данные и ключи, и по дизайну не маршрутизирует и не назначает задачи.
Пересмотр заслуживает проверки, поскольку подписывающий без знания задачи не может привязать подпись к идентификатору задачи. Злоумышленник, который копирует подлинный подписанный ключ рабочего в другую запись заявления, всё равно не имеет соответствующего приватного ключа, поэтому полезная нагрузка остаётся нечитаемой. Итог — задача, которую никто не может обработать — отказ в обслуживании, с сохранённой конфиденциальностью.
Остаются три ограничения, и раскрытие упоминает все три: открытый текст существует в памяти рабочего во время выполнения задачи, тайминг задачи раскрывает метаданные, а конструкция derivation ключа отмечена автором для улучшения.

Совет

Это открытие существует, потому что архитектура была размещена в общих ресурсах. Публикация сделала возможной независимую оценку, и именно поэтому разрыв проявился здесь, а не в отчёте о инциденте. Проprietary версия этой системы имела бы ту же проблему, но никто не был бы в положении сказать об этом.
Я ценю вклад, и модель заслуживает того уровня проверки, который она привлекла. Центральное утверждение остаётся верным, и это форма, которую я хочу видеть в более системах, потому что архитектура, которая никогда не хранит конфиденциальные данные, имеет меньшую регуляторную поверхность, чем та, которая это делает.
Рекомендация узкая: аутентифицировать эфемерный открытый ключ работника до того, как устройство зашифрует данные для него. Одна подпись, проверенная на устройстве, при нулевых затратах, делает модель достойной внедрения. Всё вышеперечисленное возникло из голосовой транскрипции разговора, охватывающего более 30 заметок, проверенной против опубликованного раскрытия, а не любого его резюме. Если эти выводы подтверждены с их стороны, они легко реализуются.