Naar de inhoud
← Alle berichten

Hoe tapeshelf video versleutelt, en waarom het geen sleutels bewaart

Een privévideo op tapeshelf is voor de eigenaar en de mensen die de eigenaar heeft gekozen. Zo houdt de app zich daaraan, en hier houdt de bescherming op.

Van upload tot stream

Je browser uploadt het bestand rechtstreeks naar een privébucket in S3-compatibele opslag, in delen van 16 MB die verdergaan als de verbinding wegvalt. Het bestand komt nooit langs onze API-servers.

Een achtergrondproces controleert het bestand met ffprobe en haalt er dan de metadata uit (plaats en tijd van opname, camera, maker, opmerkingen) door het opnieuw weg te schrijven zonder het opnieuw te coderen. Dat opgeschoonde bestand is wat mensen downloaden. Video’s die vóór 18 oktober 2026 zijn geüpload, houden hun metadata.

H.264-video tot 1080p die nog een paar controles doorstaat, wordt alleen opnieuw verpakt; dat duurt seconden. Al het andere wordt omgezet naar H.264 tot 1080p. Daarna knipt ffmpeg het resultaat in HLS-segmenten van zes seconden, die Safari zelf afspeelt en andere browsers via hls.js.

De segmenten versleutelen

ffmpeg kan HLS zelf versleutelen, maar wil de sleutel dan in een bestand op schijf hebben. We wilden op geen enkele schijf een sleutel, dus het achtergrondproces versleutelt de segmenten zelf:

  • elk segment wordt versleuteld met AES-128 in CBC-modus, de methode die de HLS-standaard voorschrijft;
  • de sleutel is 16 bytes, uniek per video, en bestaat alleen in het geheugen van het proces zolang het werkt;
  • de initialisatievector is het volgnummer van het segment, en dat is precies wat een HLS-speler aanneemt als de playlist er geen noemt.

Alleen de versleutelde segmenten en hun playlist gaan naar de privébucket. De tijdelijke bestanden van het proces worden verwijderd als de taak klaar is.

Sleutels die nooit worden opgeslagen

Daarna wordt de sleutel nergens bewaard. In plaats van een willekeurige sleutel te maken en die te bewaken, leidt tapeshelf hem af telkens als hij nodig is:

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

Bewerk je een video, dan gaat de versie omhoog en krijgt hij een nieuwe sleutel.

De hoofdsleutel is één geheim in de configuratie van de server. Hij staat niet in de database, niet in de buckets en niet in de back-ups. Een kopie van de database bevat geen videosleutels en de bucket bevat alleen versleutelde segmenten, dus een aanvaller zou ook de configuratie van de server nodig hebben.

Raak je de hoofdsleutel kwijt, dan speelt geen enkele video meer af, en geen databaseback-up brengt hem terug. Dat is vooral belangrijk als je tapeshelf op je eigen server draait.

Drie verzoeken als je op afspelen drukt

  1. Afspelen. De API controleert of je mag kijken: je bent de maker, de video staat op je plank, of hij is openbaar. Dan geeft de API een playlistadres terug met een ondertekend token erin, dat de video en jou noemt (of niemand, als je niet bent ingelogd) en een uur geldig is.
  2. Playlist. De API controleert het token en je toegang opnieuw en herschrijft de playlist ter plekke. Elk segment wordt een ondertekende opslaglink, en de regel met de sleutel wijst terug naar de API.
  3. Sleutel. Het token moet voor deze video zijn. Bij een privévideo moet je ingelogde sessie ook horen bij de persoon die in het token staat. Pas dan leidt de API de sleutel af en stuurt de 16 bytes.

Een tijdelijke link heeft geen account om te controleren, dus op de pagina ervan noemt het token de link. Bij elk verzoek wordt gecontroleerd of de link nog werkt en de video nog bevat, en het token leeft nooit langer dan de link. Video’s die een gast bij een ruil heeft gekregen, spelen op dezelfde manier af op de ruilpagina, een week lang.

Beslissingen over toegang worden een minuut in de cache bewaard, zodat een film van twee uur niet bij elk verzoek de database belast. Een verwijderde video kan binnen die minuut nog worden gestart. Een tijdelijke link die verloopt of wordt ingetrokken, stopt meteen. Hoe dan ook: een speler die al loopt, houdt zijn sleutel en segmentlinks en kan doorspelen.

Segmentlinks zijn ondertekend en verlopen ook, na een uur of langer. De speler laadt de playlist één keer, en met korte links zou een simpele pauze al misgaan. Verloopt er een, dan vraagt de speler opnieuw om afspelen en gaat hij verder op dezelfde plek. Zonder de sleutel is een segment hoe dan ook nutteloos.

Waarom er geen bestand te pakken is

De speler krijgt nooit een link naar het videobestand. Hij krijgt een playlist die aan een token vastzit, versleutelde stukjes, en een sleutel achter een controle. Kopieer je het playlistadres van een privévideo naar de browser van een vriend, dan speelt er niets af, want de sleutel heeft jouw sessie nodig.

Downloaden is een aparte zaak. Wie ingelogd is, kan downloaden wat die mag bekijken. Zonder account kun je alleen downloaden via een tijdelijke link die iemand je heeft gestuurd, of, een week lang, wat je als gast bij een ruil hebt gekregen. Een downloadlink is twee minuten geldig.

Afbeeldingen werken anders. Covers, de 16 frames uit elke video en het framevoorbeeld dat daarvan wordt gemaakt, staan in een openbare bucket onder lange willekeurige namen, en die bucket kan niet worden opgesomd. Het voorbeeld van een privévideo is met opzet zichtbaar: het laat een bezoeker zien waar die om zou vragen.

Waartegen dit beschermt

  • Wie geen toegang heeft, krijgt geen playlist, geen segment en geen sleutel.
  • Een uitgelekte segmentlink is versleutelde ruis. Een uitgelekte playlistlink naar een privévideo werkt niet zonder de sessie van de persoon voor wie hij is uitgegeven, en verloopt sowieso binnen een uur.
  • Een gestolen kopie van de database onthult geen sleutels.

Waartegen niet

  • Wie kan kijken, kan opnemen. Iemand met toegang kan het scherm opnemen of de stream met de juiste hulpmiddelen opslaan. Die persoon heeft de sleutel op rechtmatige wijze gekregen. tapeshelf heeft geen DRM. Echte DRM zoals Widevine of FairPlay hangt af van commerciële licentieservers, en houdt nog steeds geen camera tegen die op een scherm is gericht.
  • De mensen met wie je deelt. Delen of ruilen geeft de ander een blijvende kopie, en die kan het bestand downloaden. Dat geldt ook voor iedereen die een tijdelijke link opent die je hebt gestuurd, zolang die werkt. Wat er daarna met het bestand gebeurt, valt buiten ons bereik. Deel met mensen die je vertrouwt.
  • De server zelf. Dit is geen end-to-endversleuteling. De server leidt de sleutels af, dus wie de server beheert, kan elke video afspelen. Op tapeshelf.com zijn dat wij, en we openen privévideo’s als dat nodig is om de dienst te laten werken en te modereren. Op een zelf gehoste installatie is dat de beheerder.

De korte versie staat op de beveiligingspagina. Wil je het liever zelf controleren dan ons op ons woord geloven: de code is open source, en je kunt hem straks zelf draaien.