Zum Inhalt springen
← Alle Beiträge

Wie tapeshelf Videos verschlüsselt und warum es keine Schlüssel speichert

Ein privates Video auf tapeshelf ist für seinen Besitzer und die Leute, die er ausgewählt hat. So hält sich die App daran, und hier endet der Schutz.

Vom Upload zum Stream

Dein Browser lädt die Datei direkt in einen privaten Bucket in S3-kompatiblem Speicher hoch, in Teilen zu 16 MB, die nach einem Verbindungsabbruch weiterlaufen. Die Datei geht nie über unsere API-Server.

Ein Hintergrundprozess prüft die Datei mit ffprobe und entfernt dann ihre Metadaten (Ort und Zeit der Aufnahme, Kamera, Autor, Kommentare), indem er sie ohne Neukodierung neu schreibt. Heruntergeladen wird diese bereinigte Datei. Videos, die vor dem 18. Oktober 2026 hochgeladen wurden, behalten ihre Metadaten.

H.264-Video mit bis zu 1080p, das ein paar weitere Prüfungen besteht, wird nur neu verpackt, was Sekunden dauert. Alles andere wird in H.264 mit bis zu 1080p umgewandelt. ffmpeg schneidet das Ergebnis dann in HLS-Segmente von sechs Sekunden, die Safari direkt abspielt und andere Browser über hls.js.

Die Segmente verschlüsseln

ffmpeg kann HLS selbst verschlüsseln, will den Schlüssel aber in einer Datei auf der Festplatte haben. Wir wollten keinen Schlüssel auf irgendeiner Festplatte, deshalb verschlüsselt der Hintergrundprozess die Segmente selbst:

  • jedes Segment wird mit AES-128 im CBC-Modus verschlüsselt, dem Verfahren, das der HLS-Standard festlegt;
  • der Schlüssel ist 16 Byte lang, für jedes Video einzigartig und existiert nur im Arbeitsspeicher des Prozesses, solange er arbeitet;
  • der Initialisierungsvektor ist die Sequenznummer des Segments, und genau davon geht ein HLS-Player aus, wenn die Playlist keinen nennt.

Nur die verschlüsselten Segmente und ihre Playlist kommen in den privaten Bucket. Die temporären Dateien des Prozesses werden gelöscht, wenn der Auftrag fertig ist.

Schlüssel, die nie gespeichert werden

Danach wird der Schlüssel nirgends aufbewahrt. Statt einen zufälligen Schlüssel zu erzeugen und zu bewachen, leitet tapeshelf ihn jedes Mal ab, wenn er gebraucht wird:

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

Wird ein Video bearbeitet, steigt die Version, und damit bekommt es einen neuen Schlüssel.

Der Hauptschlüssel ist ein einziges Geheimnis in der Konfiguration des Servers. Er steht nicht in der Datenbank, nicht in den Buckets und nicht in den Backups. Eine Kopie der Datenbank enthält keine Videoschlüssel, und der Bucket enthält nur verschlüsselte Segmente, ein Angreifer bräuchte also auch die Konfiguration des Servers.

Geht der Hauptschlüssel verloren, spielt kein Video mehr, und kein Datenbank-Backup bringt ihn zurück. Das ist vor allem wichtig, wenn du tapeshelf auf deinem eigenen Server betreibst.

Drei Anfragen, wenn du auf Abspielen drückst

  1. Wiedergabe. Die API prüft, ob du ansehen darfst: Du bist der Autor, das Video steht in deinem Regal, oder es ist öffentlich. Dann gibt sie eine Playlist-Adresse mit einem signierten Token zurück, das das Video und dich nennt (oder niemanden, wenn du nicht angemeldet bist) und eine Stunde gilt.
  2. Playlist. Die API prüft das Token und deinen Zugriff noch einmal und schreibt die Playlist im Flug um. Jedes Segment wird zu einem signierten Speicherlink, und die Schlüsselzeile zeigt zurück auf die API.
  3. Schlüssel. Das Token muss für dieses Video gelten. Bei einem privaten Video muss außerdem deine angemeldete Sitzung zu der Person gehören, die im Token steht. Erst dann leitet die API den Schlüssel ab und schickt seine 16 Byte.

Bei einem temporären Link gibt es kein Konto zu prüfen, deshalb nennt das Token auf seiner Seite den Link. Jede Anfrage prüft, ob der Link noch gilt und das Video noch enthält, und das Token überlebt den Link nie. Videos, die ein Gast bei einem Tausch bekommen hat, laufen auf der Tauschseite genauso, eine Woche lang.

Zugriffsentscheidungen werden eine Minute lang zwischengespeichert, damit ein zweistündiger Film nicht bei jeder Anfrage die Datenbank belastet. Ein gelöschtes Video lässt sich innerhalb dieser Minute noch starten. Ein temporärer Link, der abläuft oder widerrufen wird, stoppt sofort. So oder so behält ein Player, der schon läuft, seinen Schlüssel und seine Segmentlinks und spielt unter Umständen weiter.

Auch Segmentlinks sind signiert und laufen ab, nach einer Stunde oder mehr. Der Player lädt die Playlist einmal, und kurze Links würden schon an einer einfachen Pause scheitern. Läuft einer ab, fordert der Player eine neue Wiedergabe an und macht an derselben Stelle weiter. Ohne den Schlüssel ist ein Segment ohnehin nutzlos.

Warum es keine Datei zum Abgreifen gibt

Der Player bekommt nie einen Link zur Videodatei. Er bekommt eine Playlist, die an ein Token gebunden ist, verschlüsselte Stücke und einen Schlüssel hinter einer Prüfung. Kopierst du die Playlist-Adresse eines privaten Videos in den Browser eines Freundes, spielt nichts, denn der Schlüssel braucht deine Sitzung.

Herunterladen ist ein eigener Weg. Angemeldete können herunterladen, was sie ansehen dürfen. Ohne Konto geht das nur über einen temporären Link, den dir jemand geschickt hat, oder eine Woche lang mit dem, was du als Gast bei einem Tausch bekommen hast. Ein Download-Link gilt zwei Minuten.

Bilder funktionieren anders. Cover, die 16 Bilder aus jedem Video und die daraus gebaute Bildvorschau liegen in einem öffentlichen Bucket unter langen zufälligen Namen, und der Bucket lässt sich nicht auflisten. Die Vorschau eines privaten Videos ist absichtlich sichtbar: Sie zeigt Besuchern, was sie anfragen würden.

Wovor das schützt

  • Wer keinen Zugriff hat, bekommt keine Playlist, kein Segment und keinen Schlüssel.
  • Ein durchgesickerter Segmentlink ist verschlüsseltes Rauschen. Ein durchgesickerter Playlist-Link zu einem privaten Video funktioniert nicht ohne die Sitzung der Person, für die er ausgestellt wurde, und läuft ohnehin innerhalb einer Stunde ab.
  • Eine gestohlene Kopie der Datenbank verrät keine Schlüssel.

Wovor nicht

  • Wer ansehen kann, kann aufnehmen. Jemand mit Zugriff kann den Bildschirm aufnehmen oder den Stream mit den richtigen Werkzeugen speichern. Den Schlüssel hat er rechtmäßig bekommen. tapeshelf hat kein DRM. Echtes DRM wie Widevine oder FairPlay hängt von kommerziellen Lizenzservern ab und kann trotzdem keine Kamera aufhalten, die auf einen Bildschirm gerichtet ist.
  • Die Leute, mit denen du teilst. Teilen oder Tauschen gibt der anderen Person eine dauerhafte Kopie, und sie kann die Datei herunterladen. Das kann auch jeder, der einen temporären Link öffnet, den du geschickt hast, solange er gilt. Was danach mit der Datei passiert, liegt außerhalb unserer Reichweite. Teile mit Leuten, denen du vertraust.
  • Der Server selbst. Das ist keine Ende-zu-Ende-Verschlüsselung. Der Server leitet die Schlüssel ab, wer ihn betreibt, kann also jedes Video abspielen. Auf tapeshelf.com sind das wir, und wir öffnen private Videos, wenn das für Betrieb und Moderation des Dienstes nötig ist. Auf einer selbst gehosteten Instanz ist es der Admin.

Die Kurzfassung steht auf der Sicherheitsseite. Wenn du lieber nachprüfst, als uns zu glauben: Der Code ist Open Source, und du wirst ihn selbst betreiben können.