До вмісту
← Усі дописи

Як tapeshelf шифрує відео і чому не зберігає ключів

Приватне відео в tapeshelf призначене для його власника й тих, кого власник вибрав. Ось як застосунок цього дотримується і де захист закінчується.

Від завантаження до потоку

Ваш браузер завантажує файл просто в приватний бакет S3-сумісного сховища частинами по 16 МБ, і якщо з’єднання обірветься, завантаження продовжиться. Через наші API-сервери файл не проходить.

Фоновий воркер перевіряє файл за допомогою ffprobe, а потім прибирає з нього метадані (місце й час зйомки, камеру, автора, коментарі), переписуючи файл без перекодування. Саме цей очищений файл люди й скачують. Відео, завантажені до 18 жовтня 2026 року, зберігають свої метадані.

Відео H.264 з роздільністю до 1080p, що проходить ще кілька перевірок, лише перепаковується, і це займає секунди. Усе інше перекодовується в H.264 з роздільністю до 1080p. Потім ffmpeg ріже результат на шестисекундні сегменти HLS, які Safari відтворює сам, а інші браузери — через hls.js.

Шифрування сегментів

ffmpeg уміє сам шифрувати HLS, але хоче, щоб ключ лежав у файлі на диску. Ми не хотіли, щоб ключ був на будь-якому диску, тож воркер шифрує сегменти сам:

  • кожен сегмент шифрується AES-128 у режимі CBC, тим методом, який визначає стандарт HLS;
  • ключ має 16 байтів, унікальний для відео й існує лише в пам’яті воркера, поки той працює;
  • вектор ініціалізації — порядковий номер сегмента, саме його припускає плеєр HLS, коли плейлист не вказує іншого.

У приватний бакет потрапляють лише зашифровані сегменти та їхній плейлист. Тимчасові файли воркера видаляються, коли завдання закінчується.

Ключі, які ніде не зберігаються

Після цього ключ ніде не зберігається. Замість того щоб згенерувати випадковий ключ і стерегти його, tapeshelf виводить його щоразу, коли він потрібен:

video key = HKDF-SHA256(master key, "video:" + video id + version) → 16 bytes

Редагування відео збільшує версію, і відео отримує новий ключ.

Головний ключ — це один секрет у конфігурації сервера. Його немає ні в базі даних, ні в бакетах, ні в резервних копіях. Копія бази даних не містить ключів відео, а бакет містить лише зашифровані сегменти, тож зловмисникові знадобилася б ще й конфігурація сервера.

Якщо втратити головний ключ, жодне відео більше не відтвориться, і жодна резервна копія бази даних його не поверне. Найважливіше це для тих, хто запускає tapeshelf на власному сервері.

Три запити, коли ви натискаєте «Відтворити»

  1. Відтворення. API перевіряє, чи можна вам дивитися: ви автор, відео є на вашій полиці або воно публічне. Потім повертає адресу плейлиста з підписаним токеном усередині, який називає відео й вас (або нікого, якщо ви не ввійшли) і діє годину.
  2. Плейлист. API ще раз перевіряє токен і ваш доступ і переписує плейлист на льоту. Кожен сегмент стає підписаним посиланням на сховище, а рядок із ключем вказує назад на API.
  3. Ключ. Токен має бути саме для цього відео. Для приватного відео ваш сеанс у акаунті також має належати людині, названій у токені. Лише тоді API виводить ключ і надсилає його 16 байтів.

У тимчасового посилання немає акаунта для перевірки, тому на його сторінці токен називає посилання. Кожен запит перевіряє, що посилання ще діє й досі містить це відео, і токен ніколи не переживає посилання. Відео, які гість отримав в обміні, так само відтворюються на сторінці обміну протягом тижня.

Рішення про доступ кешуються на хвилину, щоб двогодинний фільм не звертався до бази даних під час кожного запиту. Видалене відео ще можна запустити протягом цієї хвилини. Тимчасове посилання, яке закінчилося чи було відкликане, перестає працювати одразу. В обох випадках плеєр, який уже працює, зберігає свій ключ і посилання на сегменти й може відтворювати далі.

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

Чому немає файлу, який можна забрати

Плеєр ніколи не отримує посилання на сам файл відео. Він отримує плейлист, прив’язаний до токена, зашифровані частини й ключ за перевіркою. Скопіюйте адресу плейлиста приватного відео в браузер друга, і нічого не відтвориться, бо ключ потребує вашого сеансу.

Скачування — окрема річ. Люди, які ввійшли в акаунт, можуть скачувати те, що їм дозволено дивитися. Без акаунта скачати можна лише за тимчасовим посиланням, яке вам надіслали, або те, що ви отримали як гість в обміні, протягом тижня. Посилання на скачування діє дві хвилини.

Із зображеннями інакше. Обкладинки, 16 кадрів, узятих із кожного відео, і покадрове прев’ю, зроблене з них, лежать у публічному бакеті під довгими випадковими назвами, а вміст бакета не можна переглянути списком. Прев’ю приватного відео видно навмисно: воно показує відвідувачеві, що саме він проситиме.

Від чого це захищає

  • Люди без доступу не отримують ні плейлиста, ні сегмента, ні ключа.
  • Посилання на сегмент, що витекло, — це зашифрований шум. Посилання на плейлист приватного відео, що витекло, не працює без сеансу людини, якій його видали, і все одно закінчується протягом години.
  • Викрадена копія бази даних не розкриває жодних ключів.

Від чого не захищає

  • Хто може дивитися, той може записати. Людина з доступом може записати свій екран або зберегти потік потрібними інструментами. Ключ їй видали законно. У tapeshelf немає DRM. Справжній DRM, як-от Widevine чи FairPlay, залежить від комерційних серверів ліцензій і все одно не зупинить камеру, спрямовану на екран.
  • Люди, з якими ви ділитеся. Коли ви ділитеся відео чи обмінюєтеся, інша людина отримує постійну копію і може скачати файл. Так само може будь-хто, хто відкриє надіслане вами тимчасове посилання, доки воно діє. Що відбудеться з файлом далі, від нас не залежить. Діліться з тими, кому довіряєте.
  • Сам сервер. Це не наскрізне шифрування. Ключі виводить сервер, тож той, хто ним керує, може відтворити будь-яке відео. На tapeshelf.com це ми, і ми відкриваємо приватні відео, коли це потрібно для роботи й модерації сервісу. На власному сервері — його адміністратор.

Коротко про все це — на сторінці про безпеку. Якщо хочете перевірити самі, а не вірити нам на слово, код відкритий, і ви зможете запустити його у себе.