[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"legal-e2ee-ru":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"body":10,"_type":491,"_id":492,"_source":493,"_file":494,"_stem":495,"_extension":496},"\u002Flegal\u002Fe2ee\u002Fru","e2ee",false,"","Как работает наше сквозное шифрование","Última actualización: junio de 2026",{"type":11,"children":12,"toc":480},"root",[13,21,26,33,58,64,69,74,78,84,89,143,149,177,197,209,213,223,229,241,253,258,264,276,288,292,298,303,374,380],{"type":14,"tag":15,"props":16,"children":18},"element","h1",{"id":17},"как-работает-наше-сквозное-шифрование",[19],{"type":20,"value":8},"text",{"type":14,"tag":22,"props":23,"children":24},"p",{},[25],{"type":20,"value":9},{"type":14,"tag":27,"props":28,"children":30},"h2",{"id":29},"коротко-говоря",[31],{"type":20,"value":32},"Коротко говоря",{"type":14,"tag":34,"props":35,"children":36},"ul",{},[37,43,48,53],{"type":14,"tag":38,"props":39,"children":40},"li",{},[41],{"type":20,"value":42},"Ваши данные шифруются на вашем устройстве и покидают его только в виде нечитаемого шифротекста. Наш сервер хранит исключительно зашифрованные BLOB'ы и не имеет доступа к открытому тексту.",{"type":14,"tag":38,"props":44,"children":45},{},[46],{"type":20,"value":47},"Все ключи выводятся из 128-битного кода восстановления, который никогда не покидает ваше устройство. Мы его не знаем и не можем восстановить.",{"type":14,"tag":38,"props":49,"children":50},{},[51],{"type":20,"value":52},"Каждая отдельная запись шифруется собственным ключом и перед расшифровкой проверяется на подлинность (Verify-before-Decrypt с Ed25519).",{"type":14,"tag":38,"props":54,"children":55},{},[56],{"type":20,"value":57},"E2EE защищает не всё: определённые метаданные (объём данных, время доступа) остаются видны, и скомпрометированное устройство или потерянный код восстановления нельзя спасти криптографией.",{"type":14,"tag":27,"props":59,"children":61},{"id":60},"что-означает-сквозное-в-нашем-контексте",[62],{"type":20,"value":63},"Что означает «сквозное» в нашем контексте",{"type":14,"tag":22,"props":65,"children":66},{},[67],{"type":20,"value":68},"Сквозное шифрование означает: открытый текст ваших данных существует только на ваших собственных устройствах. Шифрование и расшифровка происходят исключительно локально. То, что синхронизируется между устройствами и хранится на нашем сервере, всегда уже зашифровано до того, как покидает устройство.",{"type":14,"tag":22,"props":70,"children":71},{},[72],{"type":20,"value":73},"Конкретно: строка данных кодируется на клиенте канонически в JSON, а затем шифруется с помощью AEAD-алгоритма. Сервер получает только непрозрачный байтовый BLOB плюс несколько служебных полей. Он не обладает ни одним из ключей, необходимых для расшифровки. Это архитектурное свойство, а не обещание: поскольку ключи никогда не доходят до сервера, он технически не может прочитать содержимое.",{"type":14,"tag":75,"props":76,"children":77},"e2ee-flow-diagram",{},[],{"type":14,"tag":27,"props":79,"children":81},{"id":80},"как-шифруются-ваши-данные",[82],{"type":20,"value":83},"Как шифруются ваши данные",{"type":14,"tag":22,"props":85,"children":86},{},[87],{"type":20,"value":88},"Мы используем проверенные, стандартизированные компоненты из библиотек @noble\u002Fciphers, @noble\u002Fhashes и @noble\u002Fcurves:",{"type":14,"tag":34,"props":90,"children":91},{},[92,103,113,123,133],{"type":14,"tag":38,"props":93,"children":94},{},[95,101],{"type":14,"tag":96,"props":97,"children":98},"strong",{},[99],{"type":20,"value":100},"AES-256-GCM",{"type":20,"value":102}," шифрует ваши записи. AES-256-GCM является AEAD-алгоритмом, который одновременно обеспечивает конфиденциальность (никто не читает с) и целостность (манипуляция выявляется). Каждая запись использует случайный 12-байтовый Nonce и 16-байтовый код аутентификации (MAC). Формат: nonce(12) ‖ ciphertext ‖ mac(16).",{"type":14,"tag":38,"props":104,"children":105},{},[106,111],{"type":14,"tag":96,"props":107,"children":108},{},[109],{"type":20,"value":110},"XChaCha20-Poly1305",{"type":20,"value":112}," шифрует материал ключей при сопряжении устройств (Key-Wrapping). Это тоже AEAD-алгоритм, но использует более длинный 24-байтовый Nonce, что делает случайные Nonce некритичными.",{"type":14,"tag":38,"props":114,"children":115},{},[116,121],{"type":14,"tag":96,"props":117,"children":118},{},[119],{"type":20,"value":120},"AAD (Associated Data)",{"type":20,"value":122}," привязывает каждый шифротекст к его метаданным — заголовку, Bucket, UUID записи, ревизии, эпохе ключа, версии схемы и дополненной длине. Эти поля аутентифицированы: если хотя бы одно из них будет изменено, расшифровка не удастся. Пустой AAD строго отклоняется (защита от Confused-Deputy).",{"type":14,"tag":38,"props":124,"children":125},{},[126,131],{"type":14,"tag":96,"props":127,"children":128},{},[129],{"type":20,"value":130},"Padding",{"type":20,"value":132}," маскирует точный размер: каждая запись дополняется до размера Bucket'а (256, 1024, 4096, 16384 или 65536 байт; выше — кратные 65536). Так размер BLOB'а раскрывает только приблизительный класс, а не точный объём данных.",{"type":14,"tag":38,"props":134,"children":135},{},[136,141],{"type":14,"tag":96,"props":137,"children":138},{},[139],{"type":20,"value":140},"Подпись Ed25519 (blob_sig)",{"type":20,"value":142}," подписывает каждый BLOB. Перед каждой расшифровкой клиент проверяет эту подпись против авторизованных ключей устройства (Verify-before-Decrypt). Проверка работает строго по RFC-8032 (zip215:false), что исключает подделки через точки низкого порядка. Манипулированные данные сразу выдают ошибку, без тихого отказа.",{"type":14,"tag":27,"props":144,"children":146},{"id":145},"ваши-ключи-остаются-на-вашем-устройстве",[147],{"type":20,"value":148},"Ваши ключи остаются на вашем устройстве",{"type":14,"tag":22,"props":150,"children":151},{},[152,154,159,161,166,168,175],{"type":20,"value":153},"Основа всего — ",{"type":14,"tag":96,"props":155,"children":156},{},[157],{"type":20,"value":158},"128-битная энтропия восстановления",{"type":20,"value":160}," — код восстановления. Из этих 16 случайных байт с помощью ",{"type":14,"tag":96,"props":162,"children":163},{},[164],{"type":20,"value":165},"HKDF-SHA256",{"type":20,"value":167}," (функция вывода ключей, которая из секрета генерирует много отделённых ключей) детерминированно выводится главный секрет и из него — дополнительные ключи: ID учётной записи, ключ шифрования ключей, ключ аутентификации (authSeed) и маршрутный ключ. Каждый вывод использует собственный версионированный ярлык (например, ",{"type":14,"tag":169,"props":170,"children":172},"code",{"className":171},[],[173],{"type":20,"value":174},"mypep\u002Fmaster\u002Fv1",{"type":20,"value":176},"), так что ключи не перекрываются.",{"type":14,"tag":22,"props":178,"children":179},{},[180,182,187,189,195],{"type":20,"value":181},"На каждую коллекцию приходится собственный ключ коллекции, и ",{"type":14,"tag":96,"props":183,"children":184},{},[185],{"type":20,"value":186},"на каждую запись и ревизию",{"type":20,"value":188}," — собственный ключ записи (",{"type":14,"tag":169,"props":190,"children":192},{"className":191},[],[193],{"type":20,"value":194},"rec\u002F\u003Cuuid>\u002F\u003Crev>",{"type":20,"value":196},"). Этот собственный ключ для каждой пары (Запись, Ревизия) обеспечивает полное разделение ключей: ни один ключ AES-GCM не используется дважды — сильная защита от атак Nonce-Reuse.",{"type":14,"tag":22,"props":198,"children":199},{},[200,202,207],{"type":20,"value":201},"Главный секрет намеренно ",{"type":14,"tag":96,"props":203,"children":204},{},[205],{"type":20,"value":206},"не хранится",{"type":20,"value":208},". Локально хранятся только выведённые значения и собственные ключи подписания\u002Fоборачивания устройства — в браузере в IndexedDB.",{"type":14,"tag":210,"props":211,"children":212},"key-derivation-diagram",{},[],{"type":14,"tag":22,"props":214,"children":215},{},[216,221],{"type":14,"tag":96,"props":217,"children":218},{},[219],{"type":20,"value":220},"Восстановление — возможность и ответственность:",{"type":20,"value":222}," весь дерево ключей зависит от кода восстановления. Мы его не сохраняем; лазейка, условное хранение ключей на сервере или серверный сброс архитектурно исключены — не только по политике, но потому что ключи технически никогда не достигают сервера. Это ядро подлинного E2EE: никто, кроме вас — даже мы — не может восстановить ваши данные без кода восстановления или сопряжённого устройства. Если код потерян и больше нет сопряжённого устройства, данные навсегда недоступны.",{"type":14,"tag":27,"props":224,"children":226},{"id":225},"что-видит-наш-сервер-и-что-нет",[227],{"type":20,"value":228},"Что видит наш сервер — и что нет",{"type":14,"tag":22,"props":230,"children":231},{},[232,234,239],{"type":20,"value":233},"Сервер хранит только зашифрованные BLOB'ы. Он ",{"type":14,"tag":96,"props":235,"children":236},{},[237],{"type":20,"value":238},"не видит",{"type":20,"value":240},": содержимое ваших записей, имена ваших коллекций (они появляются только как непрозрачный HMAC-SHA256-Bucket) или ваши ключи.",{"type":14,"tag":22,"props":242,"children":243},{},[244,246,251],{"type":20,"value":245},"Честно говоря, он видит ",{"type":14,"tag":96,"props":247,"children":248},{},[249],{"type":20,"value":250},"некоторые метаданные",{"type":20,"value":252},": непрозрачные значения Bucket'а, ревизии записей, приблизительный размерный класс через Padding, частоту синхронизации, ID устройств (как SHA-256-хэш ключей устройства) и позицию курсора при выравнивании. Из этого можно вывести, что учётная запись активна и примерно сколько и какой объём данных перемещается когда — но не то, о чём это содержательно.",{"type":14,"tag":22,"props":254,"children":255},{},[256],{"type":20,"value":257},"Разрешение конфликтов работает чисто через ревизии (более высокая ревизия выигрывает, «Last-Write-Wins»), потому что сервер не знает содержимое и не может содержательно объединять. Аутентификация выполняется посредством Challenge-Response с Ed25519 и последующим JWT-токеном; список устройств подписывается вашим ключом аутентификации и проверяется исключительно на клиенте.",{"type":14,"tag":27,"props":259,"children":261},{"id":260},"несколько-устройств-сопряжение",[262],{"type":20,"value":263},"Несколько устройств (сопряжение)",{"type":14,"tag":22,"props":265,"children":266},{},[267,269,274],{"type":20,"value":268},"Новое устройство, например браузер, сопрягается с телефоном через ",{"type":14,"tag":96,"props":270,"children":271},{},[272],{"type":20,"value":273},"QR-код",{"type":20,"value":275},". QR передаёт открытые ключи устройства браузера напрямую (out-of-band), не через сервер — это защищает обмен ключами от атак Man-in-the-Middle. Телефон упаковывает Identity-Bundle (ключи данных учётной записи, ключ аутентификации, ID учётной записи, маршрутный ключ) с помощью X25519-ECDH и XChaCha20-Poly1305 исключительно для браузера и передаёт его в зашифрованном виде.",{"type":14,"tag":22,"props":277,"children":278},{},[279,281,286],{"type":20,"value":280},"После расшифровки браузер показывает ",{"type":14,"tag":96,"props":282,"children":283},{},[284],{"type":20,"value":285},"отпечаток",{"type":20,"value":287}," (SHA-256 ID учётной записи в виде групп в шестнадцатеричной форме). Если он совпадает с отображением на телефоне, гарантируется, что вы получили правильный Bundle. Веб-клиенты не имеют собственного кода восстановления: при потере памяти браузера вы просто повторно сопрягаетесь с телефоном.",{"type":14,"tag":289,"props":290,"children":291},"pairing-diagram",{},[],{"type":14,"tag":27,"props":293,"children":295},{"id":294},"чего-это-не-защищает",[296],{"type":20,"value":297},"Чего это НЕ защищает",{"type":14,"tag":22,"props":299,"children":300},{},[301],{"type":20,"value":302},"E2EE мощно, но не является панацеей. Честно о границах:",{"type":14,"tag":34,"props":304,"children":305},{},[306,316,326,336,354,364],{"type":14,"tag":38,"props":307,"children":308},{},[309,314],{"type":14,"tag":96,"props":310,"children":311},{},[312],{"type":20,"value":313},"Скомпрометированное устройство:",{"type":20,"value":315}," вредоносное ПО в контексте браузера или прямой доступ к IndexedDB может читать локально хранимые ключи и таким образом расшифровать всё. Локальная база данных лежит в открытом виде.",{"type":14,"tag":38,"props":317,"children":318},{},[319,324],{"type":14,"tag":96,"props":320,"children":321},{},[322],{"type":20,"value":323},"Потерянный код восстановления:",{"type":20,"value":325}," без кода и без сопряжённого устройства пути назад нет. Не существует ротации ключей и механизма резервной копии.",{"type":14,"tag":38,"props":327,"children":328},{},[329,334],{"type":14,"tag":96,"props":330,"children":331},{},[332],{"type":20,"value":333},"Метаданные:",{"type":20,"value":335}," объёмы данных, размерные классы, шаблоны доступа и временные метки остаются видимы для сервера.",{"type":14,"tag":38,"props":337,"children":338},{},[339,344,346,352],{"type":14,"tag":96,"props":340,"children":341},{},[342],{"type":20,"value":343},"Фото-BLOB'ы:",{"type":20,"value":345}," фотографии адресуются по контенту (",{"type":14,"tag":169,"props":347,"children":349},{"className":348},[],[350],{"type":20,"value":351},"blob_id = sha256(blob)",{"type":20,"value":353},"). Кто уже владеет открытым текстом, может проверить, была ли загружена именно эта фотография.",{"type":14,"tag":38,"props":355,"children":356},{},[357,362],{"type":14,"tag":96,"props":358,"children":359},{},[360],{"type":20,"value":361},"Враждебный сервер:",{"type":20,"value":363}," он не может прочитать или подделать содержимое (Verify-before-Decrypt защищает), но он мог бы задержать данные или повторно доставить старые подписанные списки устройств (Replay). Ущерб от такого Replay ограничен: устройство регистрируется идемпотентно, так что переигранный старый список не перезапишет текущее состояние. Новые допустимые данные сервер не может придумать.",{"type":14,"tag":38,"props":365,"children":366},{},[367,372],{"type":14,"tag":96,"props":368,"children":369},{},[370],{"type":20,"value":371},"Ключ аутентификации:",{"type":20,"value":373}," кто получит ключ аутентификации, может изменить список устройств и повторно аутентифицироваться. Он должен оставаться секретным.",{"type":14,"tag":27,"props":375,"children":377},{"id":376},"криптографические-компоненты-в-обзоре",[378],{"type":20,"value":379},"Криптографические компоненты в обзоре",{"type":14,"tag":34,"props":381,"children":382},{},[383,392,401,411,420,430,440,450,460,470],{"type":14,"tag":38,"props":384,"children":385},{},[386,390],{"type":14,"tag":96,"props":387,"children":388},{},[389],{"type":20,"value":100},{"type":20,"value":391}," — шифрование записей (AEAD); 12-байтовый Nonce, 16-байтовый MAC.",{"type":14,"tag":38,"props":393,"children":394},{},[395,399],{"type":14,"tag":96,"props":396,"children":397},{},[398],{"type":20,"value":110},{"type":20,"value":400}," — Key-Wrapping при сопряжении (AEAD); 24-байтовый Nonce, 16-байтовый MAC.",{"type":14,"tag":38,"props":402,"children":403},{},[404,409],{"type":14,"tag":96,"props":405,"children":406},{},[407],{"type":20,"value":408},"Argon2id v1.3",{"type":20,"value":410}," — на основе пароля, устойчивая к памяти производная (стандарт: 64 МиБ, 3 итерации, 4 дорожки); доступна для будущих функций на основе пароля, но НЕ для кода восстановления — это уже 128-битная случайная энтропия и не требует Padding памяти.",{"type":14,"tag":38,"props":412,"children":413},{},[414,418],{"type":14,"tag":96,"props":415,"children":416},{},[417],{"type":20,"value":165},{"type":20,"value":419}," — вывод всех ключей из кода восстановления, отделённый по доменам через версионированные ярлыки; 32-байтовый вывод.",{"type":14,"tag":38,"props":421,"children":422},{},[423,428],{"type":14,"tag":96,"props":424,"children":425},{},[426],{"type":20,"value":427},"HMAC-SHA256",{"type":20,"value":429}," — непрозрачная маршрутизация коллекций (расчёт Bucket'а).",{"type":14,"tag":38,"props":431,"children":432},{},[433,438],{"type":14,"tag":96,"props":434,"children":435},{},[436],{"type":20,"value":437},"SHA-256",{"type":20,"value":439}," — хеширование для отпечатков, ID устройств и адресации фото.",{"type":14,"tag":38,"props":441,"children":442},{},[443,448],{"type":14,"tag":96,"props":444,"children":445},{},[446],{"type":20,"value":447},"Ed25519 (RFC-8032-strict, zip215:false)",{"type":20,"value":449}," — подписи для записей, списка устройств и аутентификации.",{"type":14,"tag":38,"props":451,"children":452},{},[453,458],{"type":14,"tag":96,"props":454,"children":455},{},[456],{"type":20,"value":457},"X25519-ECDH",{"type":20,"value":459}," — обмен ключами при сопряжении устройств.",{"type":14,"tag":38,"props":461,"children":462},{},[463,468],{"type":14,"tag":96,"props":464,"children":465},{},[466],{"type":20,"value":467},"Padding-Buckets",{"type":20,"value":469}," (256 Б до 65536 Б, выше — кратные 65536) — обфускация размера.",{"type":14,"tag":38,"props":471,"children":472},{},[473,478],{"type":14,"tag":96,"props":474,"children":475},{},[476],{"type":20,"value":477},"Длина ключа",{"type":20,"value":479}," последовательно 32 байта (256 бит).",{"title":7,"searchDepth":481,"depth":481,"links":482},2,[483,484,485,486,487,488,489,490],{"id":29,"depth":481,"text":32},{"id":60,"depth":481,"text":63},{"id":80,"depth":481,"text":83},{"id":145,"depth":481,"text":148},{"id":225,"depth":481,"text":228},{"id":260,"depth":481,"text":263},{"id":294,"depth":481,"text":297},{"id":376,"depth":481,"text":379},"markdown","content:legal:e2ee:ru.md","content","legal\u002Fe2ee\u002Fru.md","legal\u002Fe2ee\u002Fru","md"]