> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blindcast.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# blindcast encrypt

> Encrypt HLS segments with AES-128-CBC and rewrite the manifest with EXT-X-KEY tags pointing at your key server.

`blindcast encrypt` takes a directory of plain HLS segments (`.ts` files + `.m3u8` manifest), encrypts each segment with AES-128-CBC, and rewrites the manifest with `EXT-X-KEY` tags pointing at your key server.

## Usage

```bash theme={null}
blindcast encrypt <directory> --content-id <id> [flags]
```

## Example

```bash theme={null}
blindcast encrypt ./segments --content-id my-video-001
```

```
Encrypting 12 segments in ./segments...
  [100%] 12/12 segments encrypted
Manifest rewritten with EXT-X-KEY tags.

Output: ./segments/encrypted/
├── manifest.m3u8     (rewritten with EXT-X-KEY)
├── seg-0.ts          (encrypted)
├── seg-1.ts          (encrypted)
└── ...
```

## Flags

| Flag                     | Default                      | Description                                                                                           |
| ------------------------ | ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| `--content-id <id>`      | *(required)*                 | Unique identifier for this content. Used for key derivation. Alphanumeric, hyphens, underscores only. |
| `--key <hex>`            | `$BLINDCAST_MASTER_KEY`      | Master key as hex string                                                                              |
| `--salt <hex>`           | `$BLINDCAST_SALT`            | Salt as hex string                                                                                    |
| `--out <directory>`      | `<input>/encrypted`          | Output directory for encrypted files                                                                  |
| `--key-server-url <url>` | `http://localhost:4100/keys` | Key server URL written into the manifest's `EXT-X-KEY` tags                                           |
| `--json`                 | —                            | Output results as JSON to stdout                                                                      |

## What happens

1. **Reads** the `.m3u8` manifest and all `.ts` segments from the input directory
2. **Derives** a content key from the master key using HKDF-SHA-256 with the content ID as info
3. **Encrypts** each segment with AES-128-CBC using the content key and a derived IV
4. **Rewrites** the manifest, adding `EXT-X-KEY` tags with `METHOD=AES-128`, the key server URL, and per-segment IVs
5. **Writes** encrypted segments and the rewritten manifest to the output directory

## IVs

Each segment gets a deterministic IV derived from `SHA-256(contentId + ":" + segmentIndex)`, truncated to 16 bytes. This prevents chosen-plaintext attacks while keeping IVs reproducible (no random state to store).

## Content ID rules

The `--content-id` value:

* Must be 1–256 characters
* Only alphanumeric characters, hyphens (`-`), and underscores (`_`)
* Is used as the HKDF info parameter — different content IDs produce different keys from the same master key

## Preparing HLS segments

The CLI encrypts pre-existing HLS segments. To create HLS segments from a video file, use FFmpeg:

```bash theme={null}
ffmpeg -i input.mp4 \
  -codec: copy \
  -start_number 0 \
  -hls_time 6 \
  -hls_list_size 0 \
  -f hls \
  segments/manifest.m3u8
```

This creates `segments/manifest.m3u8` with `seg-0.ts`, `seg-1.ts`, etc. Then encrypt them with `blindcast encrypt ./segments --content-id my-video`.
