12

What is the correct syntax to do CENC encryption with ffmpeg?

The ffmpeg 3.0 release notes include "Common Encryption (CENC) MP4 encoding and decoding support", and the files libavformat/movenccenc.h and libavformat/movenccenc.c seem to include everything needed to encrypt MP4 files according to the Common Encryption standard.

However, I can't find any documentation on this topic in the ffmpeg manual pages.

Regards

Roland Le Franc
  • 186
  • 1
  • 1
  • 10
  • 1
    You mean with the ffmpeg command line interface? If so, this is not a programming question and should be migrated to [su]. – Artjom B. Jul 06 '17 at 17:53

2 Answers2

15

Mulvya's answer covered the ffmpeg-options.

I'm just adding a concrete example and talk about playback too, as i did some experiments yesterday (independently).

Encryption example

ffmpeg -i SampleVideo_1280x720_1mb.mp4 -vcodec copy -acodec copy -encryption_scheme cenc-aes-ctr -encryption_key 76a6c65c5ea762046bd749a2e632ccbb -encryption_kid a7e61c373e219033c21091fa607bf3b8 SampleVideo_1280x720_1mb_encrypted.mp4

(of course usage might be different for your case; i just remuxed video and audio)

Playback / Decoding

ffplay

ffplay SampleVideo_1280x720_1mb_encrypted.mp4 -decryption_key 76a6c65c5ea762046bd749a2e632ccbb

But as this is more or less a prototype-player, one might want to use something more powerful.

mpv

mpv --demuxer-lavf-o=decryption_key=76a6c65c5ea762046bd749a2e632ccbb SampleVideo_1280x720_1mb_encrypted.mp4

There is some discussion here as my first expected command-line did not behave as expected!

Edit: trying to address Reino's questions

The encryption_key is just 128 bit = 16 bytes encoded as Hex (following the usage of AES-128-CTR). So random.org with a configuration of 16 bytes and hex.encoding would be a valid key (but i'm not recommending to trust external resources in general). I used python's secrets module which boils down to: secrets.token_hex(16). This encryption_key will be needed for decoding.

The encryption_kid Key ID is just an identifier for this key, probably needed for more complex usage-patterns (i'm !guessing! you could do something like: hey video... which of my 1000 keys do i need for you?). I suppose it's mandatory to pass it, but it's not required for decoding (if you know which key to use for which video).

The official references would be:

  • Standard
  • ffmpeg implementation: docs (available through command-line) or a short extraction
sascha
  • 27,544
  • 6
  • 57
  • 97
  • I'm new to this whole encryption thing and I'm trying to understand how to generate an encryption key on my own. Can you tell me? Did you use a tool for that perhaps? What exactly is this encryption key identifier? What does it do and is it an obligatory parameter? – Reino Sep 09 '18 at 10:41
  • 1
    Too bad you don't get e-mail-notification for edited posts, because I only now saw your edited post. Thanks. For Bash https://stackoverflow.com/a/49284034/2703456 did it for me. And it appears even my favorite tool [Xidel](http://videlibri.sourceforge.net/xidel.html) can do it: `xidel -s -e 'random-seed(),string-join((1 to 32) ! x:integer-to-base(random(16),16))'`. The `-encryption_kid`-parameter appears mandatory when encrypting, because you'd get `[mp4 @ 051e28c0] Invalid encryption kid len 0 expected 16` otherwise. – Reino Sep 23 '18 at 20:21
  • Note that the CENC flags are not applied when generating DASH. Also I get an error "saio atom found without saiz" when I try to play back the encrypted mp4 with mpv or ffplay - I haven't had time to figure out why yet. – Peter Tseng Feb 27 '19 at 02:57
  • Just in case anyone runs into this, ffplay/mpv will fail if you use these flags: `-movflags frag_keyframe+empty_moov+default_base_moof+faststart -frag_duration 2000000` – Peter Tseng May 02 '19 at 23:16
  • In general `encryption_kid` is used for different DRM solutions. We pass the `encryption_kid` to the player, the player then passes that `encryption_kid` to a licensing server which then gives the player the key. DRM (with respect to video playback) tends to mean encrypted video + smart key management – DanHabib May 07 '19 at 15:53
7

Running ffmpeg -h muxer=mp4 will produce all the available options for the MP4 muxer, among which are

-encryption_scheme <string>     E....... Configures the encryption scheme, allowed values are none, cenc-aes-ctr
-encryption_key    <binary>     E....... The media encryption key (hex)
-encryption_kid    <binary>     E....... The media encryption key identifier (hex)

These options and their values should be placed after all the inputs and before the output filename.

Gyan
  • 63,018
  • 7
  • 100
  • 141