Вложения: зашифровать файл и защитить ключ
Зашифрованный файл может оказаться практически открытым, если ключ его расшифрования путешествует в доступных серверу метаданных. В таком случае надёжность алгоритма не спасает модель: рядом с закрытым контейнером лежит инструкция, как его открыть.
В ZionVox граница file key вынесена отдельно. В Z06 речь шла о сессии сообщения; здесь разберу, что именно эта сессия должна защищать при передаче вложения.
Большой ciphertext удобно хранить и перевозить отдельно от короткого сообщения. Но получателю нужны и байты, и данные для расшифрования. Поэтому появляются два потока: доставка зашифрованного объекта и доставка защищённого описания его ключа.
В frontend/src/crypto/attachmentFileKeyWire.ts есть buildAttachmentEncryptedPlaintext и parseAttachmentEncryptedPlaintext. Внутренний объект содержит zvAttachmentKeysV1 и необязательный caption. У строки ключевого описания определены fileKeyB64, fileIvB64 и необязательный thumbIvB64.
Если один клиент перестал отправлять fileKeyB64 открыто, старый или некорректный клиент всё ещё может его прислать. Поэтому ADR описывает и серверную очистку новых metadata. Клиентская дисциплина и серверная политика закрывают разные входы.
После расшифрования сообщения клиент разбирает внутренний wire и обогащает описания вложений ключевыми данными. В enrichAttachmentsWithFileKeys строки сопоставляются по индексу; в коде предусмотрен fallback на первую строку. Уже существующее непустое legacy-поле не переписывается этим helper.
В helper явно сохранено чтение legacy. Это прагматичный компромисс: иначе обновление формата лишило бы доступности старые данные. Но совместимость расширяет число вариантов, которые нужно правильно различать.
Дальше в серии, в Z16, будет доставка частей от нескольких источников с seeding и resume. Для неё важно именно разделение слоёв: peer может раздавать проверенный ciphertext, не становясь владельцем file key.
В полной статье — последовательность операций, разбор отказов и практический чек-лист. Я проектирую такие архитектуры и для клиентских проектов.
https://arhellist.ru/blog/vlozheniya-zashifrovat-fayl-i-zaschitit-klyuch/