Что такое клиентское шифрование? Ваш браузер делает всю работу
Клиентское шифрование означает, что файлы шифруются в браузере до загрузки. Максимальная конфиденциальность и контроль.
Клиентское шифрование означает, что браузер или приложение шифрует файлы прямо на вашем устройстве — до того как они покидают его. Сервер получает только шифртекст — вывод AES-256-GCM, неотличимый от случайного шума — а ключ дешифрования никогда не покидает клиент. Это противоположность серверного шифрования, при котором провайдер держит ключи и теоретически может прочитать ваши файлы. Web Crypto API (window.crypto.subtle) делает это возможным в любом современном браузере без плагинов, работая со скоростью около 2–3 ГБ/с на аппаратуре с AES-NI. Такие сервисы, как HexaTransfer, SwissTransfer, Tresorit Send и Proton Drive, используют эту модель, гарантируя конфиденциальность файлов даже при компрометации самого сервиса.
Браузер как криптографический движок
Пять лет назад полноценное шифрование требовало установки десктопного приложения или использования PGP из командной строки. Web Crypto API, стандартизированный W3C в 2017 году, изменил это. Он предоставляет AES-GCM, RSA-OAEP, ECDH, HMAC, PBKDF2 и SHA-256 напрямую JavaScript-коду в любом современном браузере — Chrome, Firefox, Safari, Edge.
Производительность больше не является узким местом. Инструкции Intel AES-NI достигают 3–5 ГБ/с на ядро для AES-256-GCM. ARM Cryptography Extensions на чипах Apple M-серии и Qualcomm Snapdragon обеспечивают аналогичную пропускную способность. Шифрование файла размером 1 ГБ в браузере занимает около 300–500 мс на ноутбуке среднего класса.
Основная трудность — работа с файлами, превышающими объём браузерной памяти. Streams API и ReadableStream позволяют обрабатывать файлы блоками по 4 МБ, шифруя каждый блок независимо с уникальным IV в режиме счётчика. Именно так сервисы поднимают планку до 10 ГБ и более.
Минимальный поток клиентского шифрования
Вот последовательность, которую выполняет типичный браузерный сервис:
// 1. Генерируем случайный 256-битный ключ AES
const key = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]
);
// 2. Читаем файл блоками
const file = fileInput.files[0];
const chunkSize = 4 * 1024 * 1024;
// 3. Шифруем каждый блок с уникальным 12-байтным IV
for (let offset = 0; offset < file.size; offset += chunkSize) {
const chunk = file.slice(offset, offset + chunkSize);
const iv = crypto.getRandomValues(new Uint8Array(12));
const ciphertext = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv }, key, await chunk.arrayBuffer()
);
// 4. Загружаем [iv || ciphertext] на сервер
}
// 5. Экспортируем ключ и встраиваем его во фрагмент URL
const keyBytes = await crypto.subtle.exportKey("raw", key);
const shareUrl = `https://example.com/d/${fileId}#k=${base64url(keyBytes)}`;
Сервер видит случайно выглядящие байты, идентификатор файла — и ничего больше. Ключ существует только в памяти браузера пользователя и во фрагменте URL.
Почему это лучше серверного шифрования
Серверное шифрование означает, что провайдер расшифровывает данные по запросу — для создания миниатюр, проверки антивирусом, обработки поисковых запросов или реакции на юридические требования. В 2023 году раскрытие информации Apple показало, что резервные копии iCloud (до введения Advanced Data Protection они не были сквозно зашифрованы) были доступны Apple и, соответственно, американским правоохранительным органам по обоснованным запросам.
Клиентское шифрование меняет это кардинально. Поскольку ключ никогда не достигает провайдера:
- Недобросовестные сотрудники не видят ничего. Инженер с доступом к базе данных получает лишь шифртекст.
- По судебному запросу выдаётся шифртекст. Провайдер может выполнить требование, передав зашифрованный blob, бесполезный без ключа.
- При утечке данных компрометируется только шифртекст. Инцидент с LastPass в 2021 году наглядно показал это: похищенные хранилища были зашифрованы, и реальному риску подверглись только пользователи со слабыми мастер-паролями.
- Сбои провайдера не компрометируют данные. Даже если компания прекратит работу, ваша локальная копия ключа (в URL) по-прежнему расшифрует файл.
Что сервер всё же видит
Клиентское шифрование защищает содержимое файлов, но не всё остальное. Сервер, как правило, наблюдает:
- Размер файла — длина шифртекста приблизительно соответствует длине открытого текста (AES-GCM добавляет 16 байт накладных расходов на каждое шифрование плюс 12-байтный IV).
- IP-адреса загрузки и скачивания с временными метками.
- Метаданные сессии из TLS-рукопожатий, включая TLS-отпечаток клиента.
- Зашифрованные имена файлов — если имена файлов не включены в зашифрованный payload, они могут раскрыться.
Хорошие клиентские сервисы шифруют имена файлов как часть заголовка шифртекста и применяют дополнение до округлённых размеров (1 МБ, 10 МБ, 100 МБ), чтобы скрыть размер. Tresorit и Proton Drive явно документируют раскрытие метаданных.
Клиентское шифрование с защитой паролем
Многие сервисы позволяют добавить пароль поверх фрагмента URL. Схема работы:
- Браузер генерирует случайный 128-битный salt и выводит ключ с помощью PBKDF2-HMAC-SHA-256 с 600 000 итерациями (рекомендация OWASP 2023) или Argon2id с параметрами
memory=64 МБ, iterations=3. - Файл шифруется производным ключом.
- Salt помещается во фрагмент URL; пароль передаётся по отдельному каналу.
- Получатель вводит пароль, и ключ повторно выводится локально.
Это превращает одноканальный обмен (когда достаточно URL) в двухфакторный: злоумышленнику нужны и ссылка, и пароль. PBKDF2 с 600 000 итерациями делает офлайн-перебор паролей стоимостью около 10 секунд на попытку на современном GPU, поэтому паролям нужна энтропия от 40 бит и выше, чтобы противостоять целенаправленным атакам — используйте 10+ символов из разнообразного алфавита.
Сдвиг доверия: от сервиса к клиентскому коду
Клиентское шифрование смещает границу доверия. Раньше вы доверяли сервису корректную обработку открытых данных. Теперь вы доверяете JavaScript, который сервис доставляет в ваш браузер при каждой загрузке страницы. Вредоносное обновление может похитить ключ до или во время шифрования.
Существуют три защитные меры разной строгости:
- Subresource Integrity (SRI) для тегов script гарантирует соответствие хеша JS известному значению.
- Аудит кода такими компаниями, как Cure53, NCC Group или Trail of Bits, подтверждает корректность логики шифрования.
- Воспроизводимые сборки позволяют независимым сторонам убедиться, что поставляемый код соответствует опубликованным исходникам.
- Заголовки Content Security Policy (CSP) блокируют сторонние скрипты, способные вмешаться в шифрование.
Наиболее строгий подход, используемый pmcrypto Proton Mail и некоторыми Electron-клиентами, предполагает подписанные бинарные файлы, а не свежий JavaScript при каждом посещении. Браузерные сервисы жертвуют частью этой строгости ради удобства установки без дополнительного ПО.
Когда клиентское шифрование особенно необходимо
Сценарии, где клиентское шифрование оправдывает немного более долгую первую загрузку:
- Юридические и медицинские документы. HIPAA 45 CFR § 164.312 и адвокатская тайна существенно выигрывают от архитектур, слепых к провайдеру.
- Журналистика и защита источников. Отправка нередактированных документов, где даже раскрытие метаданных несёт риск.
- Корпоративная интеллектуальная собственность. Материалы для совета директоров, финансовые модели, документы M&A, где угрозы со стороны инсайдеров у провайдера передачи файлов являются реальной угрозой.
- Личные документы. Налоговые документы, паспорта, медицинские анализы — файлы, которые вы не хотели бы видеть в заголовках об утечках данных у провайдера.
Для файлов с низкой чувствительностью (фотография с совещания, рецепт) традиционного серверного шифрования вполне достаточно.
Как распознать настоящее клиентское шифрование
Четыре признака того, что сервис действительно использует клиентское шифрование:
- Фрагменты URL содержат ключ. В URL после
#есть текст, похожий на base64-кодированные случайные байты. - Загрузки — это шифртекст. Откройте DevTools → Network во время загрузки; тело запроса должно выглядеть как случайные байты, а не ваше имя файла.
- Большие файлы всё равно работают быстро. Настоящий клиентский поток передаёт блоки; он не перезагружает их на шлюз серверного шифрования.
- Политика конфиденциальности гласит: «Мы не можем расшифровать ваши файлы». В сочетании с техническим описанием, а не только маркетинговым текстом.
Сервисы, которые соответствуют критериям: E2EE-уровень SwissTransfer, Tresorit Send, общие ссылки Proton Drive, Mega.nz и HexaTransfer. Сервисы, которые не соответствуют: стандартный WeTransfer, Google Drive, общие ссылки Dropbox.
Применение на практике
Если вы хотите попробовать клиентское шифрование сегодня, откройте DevTools и следите за вкладкой Network во время загрузки файла. Вы должны увидеть зашифрованный blob, отправляемый на сервер, и ключ в строке адреса, который никогда не появляется ни в одном запросе. В этом и состоит весь смысл.
Попробуйте на hexatransfer.com — бесплатно, без регистрации, до 10 ГБ.
Безопасная отправка больших файлов со сквозным шифрованием
Передавайте файлы до 10 ГБ бесплатно со сквозным шифрованием. Регистрация не требуется. Ваши файлы шифруются в браузере перед загрузкой — никто другой не может их прочитать.
Отправить файл