HLS encryption with AES-128
Updated 06 Oct 2026The HLS output of a channel can be encrypted with AES-128: every segment is encrypted with a 128-bit key that the Castreon server creates by itself, and the players fetch the key from the same server. Every HLS player can play it — Safari and iPhone, Android (ExoPlayer / Media3), hls.js, Video.js, VLC, Smart TVs and set-top boxes — without a DRM provider and without extra costs.
Available from Castreon 1.0.5, on all plans.
What it protects — and what it does not
- The segments are useless without the key: copied from a cache, a CDN or the disk, they cannot be played.
- The key is served with the same access rules as the stream — the Token for players and the Allowed addresses — and is never kept in caches on the way.
- A viewer who is allowed to watch also receives the key. AES-128 keeps out those who are not allowed; it does not stop an allowed viewer from recording. For paid content with protection on the device itself, use DRM — Widevine, PlayReady and FairPlay (Enterprise).
Turn it on
- Open the channel → Edit → the HLS output.
- Set Encryption to AES-128.
- Choose Key rotation:
- only at start — a new key every time the channel starts;
- every 10 minutes, every hour (default) or once a day — the key also changes while the channel runs.
- Save. Under Delivery the address appears as HLS · AES-128 — it is the same address as before (
http://<domain>/live/channel1/index.m3u8).
AES-128 works with TS segments. With the Container set to automatic, H.264 channels use TS, so nothing else needs to be changed. With the container set to fMP4 (CMAF) the option cannot be chosen; HEVC and AV1 always use fMP4, so with them the channel does not start and its log says why — choose H.264 for this channel or use DRM.
With several qualities (ABR), every quality is encrypted.
The keys
- The keys are created on the server and kept next to the segments, in
/live/<channel>/keys/. The playlist tells the player which key belongs to which segment. - When the key changes, the new segments use the new key; the old keys stay available for the length of the interval plus 10 minutes (at least the last three), so viewers who are a little behind keep watching without interruption.
- Players need nothing special: they read the key address from the playlist.
Use HTTPS
The key travels like any other file. Over plain HTTP it can be read on the network; over HTTPS it cannot. Put the panel and the delivery behind HTTPS and set the Public domain in Settings → Instance to https://… — see WebRTC → HTTPS for the panel for a ready configuration with Caddy or nginx.
With a CDN in front of Castreon, let the CDN cache the segments but not /live/<channel>/keys/ (Castreon already sends Cache-Control: no-store for the keys), and pass the token through.
What is not encrypted
AES-128 applies only to the HLS output. DASH, LL-HLS, HTTP-TS, WebRTC and the push outputs (SRT, RTMP, UDP, RIST) are not affected — for them use the Allowed addresses, the token, SRT/RIST encryption or DRM.
The preview in the panel keeps working on encrypted channels.
If it does not work
- AES-128 cannot be chosen — the HLS Container is set to fMP4 (CMAF). Choose TS or automatic.
- The channel does not start: "AES-128 encryption of the HLS output works only with TS segments…" — the profile is HEVC or AV1, which use fMP4. Use H.264 for this channel, or DRM.
- The player loads the playlist but not the picture — it cannot get the key: check the token and the allowed addresses for the viewer, and that a page served over HTTPS does not load the stream over HTTP (browsers block mixed content).
- The channel log says "HLS encryption: could not create the key" — the HLS folder is not writable (disk full or permissions).