Skip to main content

pycenc

Pure-Python CENC (Common Encryption) decryptor for fragmented MP4.

pycenc decrypts cenc-encrypted DASH/fragmented MP4 files (the scheme used by Widevine, PlayReady, and ClearKey) using a content key you already have. It is a pure-Python alternative to Bento4's mp4decrypt — no compiled dependencies, just the cryptography library.

What this is: an implementation of ISO/IEC 23001-7 (CENC) — a published standard for common encryption of fragmented MP4. It performs standard AES-128-CTR decryption given a content key.

What this is not: it does not obtain keys. There is no CDM, no key exchange, no license server, no network access. You supply the key; the library does the crypto. (Obtaining keys from a DRM system is a separate concern this library does not address.)

Install

pip install pycenc
# or, from source:
uv tool install .   # or: pip install .

CLI

pycenc --key KID:KEY input.m4s output.mp4
# KID is accepted but informational (single key decrypts all samples):
pycenc --key 3adcf39a811a5ab45f901e5b835b688c input.m4s output.mp4

Library

from pycenc import decrypt_bytes, decrypt_file

# in-memory
with open("encrypted.m4s", "rb") as f:
    data = f.read()
clear = decrypt_bytes(key_bytes, data)          # -> bytes

# file-based
with open("encrypted.m4s", "rb") as fi, open("decrypted.mp4", "wb") as fo:
    decrypt_file(key_bytes, fi, fo)

key_bytes is a 16-byte AES-128 content key.

How it works

  1. Walks the ISO BMFF box tree (moov/trak/moof/traf/mdat) without external parsers.
  2. For each fragment, reads the senc box (per-sample IVs + subsample split) and the trun box (sample sizes), then decrypts each sample's encrypted bytes with AES-128-CTR.
  3. Auto-detects the IV size (8 or 16 bytes) and whether subsample encryption is used — some files in the wild carry non-compliant senc flags or tenc reporting per_sample_iv_size=0, so detection validates each interpretation against the box length rather than trusting the flags.
  4. Produces a clean, muxable MP4: strips the CENC boxes (sinf/senc/saiz/saio/pssh), restores sample-entry types (encv→avc1, enca→mp4a), recomputes box sizes, and fixes trun.data_offset. The output opens directly in ffmpeg and standard players.

Supported

Scheme Status
cenc (AES-CTR, full-sample & subsample) ✅
cbcs (pattern, AES-CBC) planned
cens (partial, AES-CTR) planned
Feature Status
Single content key per file ✅
Multi-key (per-track KID matching) planned

Limitations

  • Single content key per file (the common case). Multi-key support is planned.
  • cenc scheme only for now; cbcs/cens are on the roadmap.
  • Reads the file into memory (fine for typical streaming segments; streaming I/O is a future improvement).

License

MIT — see LICENSE.

Release files for pycenc 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pycenc 0.1.0
File Size Uploaded
pycenc-0.1.0.tar.gz 9.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pycenc 0.1.0
File Interpreter ABI Platform
pycenc-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 20.3 kB

Release files / pycenc-0.1.0.tar.gz

Download URL pycenc-0.1.0.tar.gz
Size 9.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6145b1990bff96016ed31810a36765e0baa67ba220a35940f8dd5972efd5031b
BLAKE2b-256 checksum
How to use checksums
a5fb29187aa79e04ca02adfb8e0995a0a9c1d87510ebfa6965d5aed62711f1e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pycenc-0.1.0-py3-none-any.whl

Download URL pycenc-0.1.0-py3-none-any.whl
Size 11.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e73308aabcf7f005327bb41ba21c598408825b7a3d88463c9843ced1405506c6
BLAKE2b-256 checksum
How to use checksums
bd636eabfe86fd6bd5717466f3f1d11038005aeecf9b34d8f8da3d77dff8ad5c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page