Как стать автором
Обновить

Жонглирование ключами: как работает on-premise облако с e2e-шифрованием

Время на прочтение6 мин
Количество просмотров3.9K
Всего голосов 19: ↑19 и ↓0+19
Комментарии18

Комментарии 18

25519 не умеет шифровать, это алгоритм Diffie-hellman. Вы используете самописный ECIES или может новый стандарт HPKE?

Ничего самописного, в libsodium все есть. Мы чуть расширили описание в теле статьи, чтобы было понятнее.
Я не понял самого главного — как победили скачивание и расшифровку больших файлов-то?
Мелкие да — можно в temporary FS положить, там расшифровать, потом отдать и удалить.

Upload без проблем делается чанками и их можно шифровать на лету.

А при download-е больших файлов сразу две проблемы — первая — как их расшифровывать на лету (ибо чанками нет способа их обрабатывать) и второе — как показать пользователю диалог сохранения такого файла?

Т.е например я хочу скачать файл размером 50 мб и чтобы было показано обычное ркршко сохранения файла. В worker и его временную память это тоже не влезет. Как Вы такое делаете?
Скачивание по блокам тоже возможно, s3 поддерживает Range. Подробнее можно почитать здесь и здесь. Даже так Firefox и Safari могут дропнуть вкладку, но уже после 20-40гб. А вот в Chrome благодаря File System Access API так можно загружать загружать файлы неограниченного размера.

Что касается отображения — процесс загрузки сначала показывается в UI облака, а затем, когда файл «собран» вызывается стандартный диалог сохранения. При этом скачивание не начинается заново, так как файл уже находится на диске во временных файлах системы.
Range — это Вы имеете ввиду, что можно качать файл кусками, правильно?
Да, я могу с помощью range запрашивать куски файла (но речь была про немножко другое), а где вы из собирать будете, если, например, файл длиной 500гб? Temp FS/local storage не даст это сделать по лимитам — 10Mb по-умолчанию.

Соответственно, показать диалог сохранения тоже не получится, так как самого собранного файла не будет физически.

А асинхронно — типа открыть скачивание файла и пихать туда чанки, считанные через range не получится — нет такого API.

Посмотрите как Mega работает, там для разных браузеров разные способы скачать и расшифровать большой файл

Вот я как раз и хотел узнать так сказать из первых рук — как работают в таком режиме здесь, в том числе на мобильных браузерах.

Но, видимо, мне не ответят.
Специально пошел за подробностями к ребятам, которые отвечают за эту фичу. Так долго потому что все сейчас немного заняты. Резюмирую:

1. Сейчас у нас есть возможность загрузить на сервер файл практически любого размера, загрузка идет по чанкам.

2. Скачивание файлов устроено сложнее, и реализация действительно во многом зависит от используемого браузера. Самый лучший вариант (мы реализовали его совсем недавно) с использованием File System API (пока что этим могут похвастать Chromium продукты: Chrome, Яндекс.Браузер, Opera, Edge и т.д.).

Если File System API доступно, то идет загрузка по чанкам с расшифровкой и последовательной записью на диск.

Если File System API недоступно (как в Firefox и Safari), то работает скачивание в потоке воркера. Выделяется область памяти ArrayBuffer и в нее последовательно идет запись чанков. Как только все чанки будут записаны, через конструктор new File формируется файл, затем создается url, по которому его можно скачать, и запускается загрузка средствами браузера.

3. При использовании File System API мы фактически не ограничены в объеме записываемого файла.

Если загрузка идет через воркер, то для скачивания файла требуется в два раза больше места (требуемое место = размер размер зашифрованного файла + размер расшифрованного файла). К тому же, в этой реализации сначала идет запись в оперативную память, поэтому многое зависит от конкретной операционной системы, ее поведения в процессе скачивания.

Вполне возможно, что Windows не даст скачать таким образом файл, который заметно больше объема оперативной памяти устройства. Скачать таким образом 30 ГБ на макбуке с объемом ОЗУ 16 ГБ можно точно, но мы не исследовали скачивание «экстремально» больших файлов в этом сценарии на всем парке операционных систем и в мобильных браузерах. Все таки, это не частый сценарий, так что подобные исследования остаются на будущее. Вместо этого сейчас команда сосредоточилась на десктопном клиенте, который позволит манипулировать большими файлами, не задумываясь об ограничениях браузеров.
Вот прямо спасибо за ответ.

А как на мобильных? ЕМНИП там вообще нет ни у кого File System API — через воркер только?

И еще наглый вопрос — а не поделятся ваши разработчками кусочком кода, который работает в воркере и расшифровыват чанки — т.е. работает без File System API (ибо с ним все понятно), ибо у меня система в таком режиме не могла переварить файлы больше 2-3мб (при 16гигах оперативки). Но, возможно, я что-то не так делаю. Браузер — FF последний.
Насколько я знаю, на мобильных тоже через воркер. (уточню).

BSC не open source, так что код под NDA. Но, возможно вам будет полезно посмотреть StreamSaver. Она умеет скачивать файлы любого размера. В нашем облаке эта штука не использовалась (так как делает запросы на внешний ресурс), но разработчики во многом ей вдохновлялись.

End-to-end шифрование - это прекрасно, но вот применительно к корпоративному файловому хранилищу возникают большие вопросы:

1. Полнотекстовым поиском по файловому хранилищу на сервере, я так понимаю, по понятным причинам пришлось пожертвовать? А это довольно важное требование, когда там скопленная за 10+ лет помойка на терабайты, которую разгрести невозможно, но вот что-то найти там периодически надо.

2. Как решается вопрос восстановления пользовательских ключей (и зашифрованных ими данных) при их утрате? Ведь для этого ключи (пользовательские или резервные) всё равно в какой-то форме должны попадать на сервер (файловый или другой) - и преимущества end-to-end шифрования в существенной степени сводятся на нет?

P.S. Я со своей стороны импортозаместил зарубежный сервер Seafile + Backblaze B2 (который тупо невозможно дальше оплачивать...) на тот же зарубежный сервер Seafile + S3QL + объектное хранилище Яндекс.Cloud. Яндексу (которому доверять, естественно, ни малейших оснований) попадают уже зашифрованные данные, бонусом S3QL даёт локальный кэш, дедупликация и сжатие. В случае полной потери доступа к зарубежному серверу (что, увы, не исключено) придётся поднять в другом месте только его (что быстро), а не копировать терабайты данных. Но шифрование не end-to-end, а на стороне сервера, в т.ч. по описанным выше причинам.

Просто наше решение немного другого класса, нежели то, что вам нужно. К сожалению, когда делаешь упор на безопасность, чем-то приходится жертвовать.

1. Полнотекстовый поиск реализовать не получится. Он бьет по безопасности хранилища и лишает смысла всю схему шифрования, которую мы используем.

2. На данный момент в случае утери ключа можно восстановить доступ только к аккаунту, файлы будут потеряны. Однако, мы рассматриваем возможность сделать восстановление при помощи парольной фразы (как в некоторых криптокошельках) в качестве опции.

Ответы на вопросы ожидаемы (а как ещё-то с end-to-end), но вот сценарий применения Вашего решения по-прежнему не очень понятен. В корпоративном окружении рисковать потерей информации, если один-единственный сотрудник утопил ноут / уволился и послал всех по адресу / умер и т.п. - как-то это кажется куда как бóльшим риском для безопасности, чем потенциальный взлом сервера с ключами.

Если в end-to-end больше чем два end-a, то он же всё равно end-to-end. Можно шифровать все ключи на "публичный ключ судного дня", доступ к которому есть только у начальства

Превью pdf открывается в iframe, так что блокировщики рекламы его иногда обрезают.

Не рассматривали вариант с "прокси" на стороне клиента, которое занимается расшифровкой?

Для чего идет шифровка зашифрованного ключа ключом A? Какой смысл несет данная операция?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий