kaltura / nginx-vod-module

NGINX-based MP4 Repackager
GNU Affero General Public License v3.0
2k stars 439 forks source link

Does the nginx-vod-module support ClearKey with an external key server for HLS and DASH? #1507

Closed nonth closed 8 months ago

nonth commented 9 months ago

I am currently able to set up the nginx-vod-module to use HLS ClearKey by configuring the vod_secret_key and vod_hls_encryption_method as aes-128. but in production I'll have separate key server to store key and iv to encryption video.

Now, my questions are:

  1. How do I set up the nginx-vod-module to use keys and initialization vectors (IV) from an external key server for ClearKey encryption in HLS and DASH?
  2. Can the nginx-vod-module expose the IV from an external key server in the m3u8 manifest? As far as I know, the nginx-vod-module will expose the IV when the vod_secret_key, vod_encryption_iv_seed, and vod_hls_container_format are set to fmp4.
erankor commented 9 months ago

The module supports two flows for encryption in HLS -

  1. Pull the key from an external server - this flow is used when vod_drm_enabled is set to on.
  2. Generate an encryption key internally using a hash function

In both flows, you can have an external server serve the key, using the vod_hls_encryption_key_uri directive. When using option 2, you would set vod_secret_key to combine some secret string with the id of the video. The external server would share the same secret, and perform the same calculation (using md5 hash).

In DASH, only option 1 is supported, there is a sample PHP script (test/dash_clear_key.php) that shows how to build the encryption/license responses.

Regarding the question about the IV -

  1. when using DRM mode, if the DRM server returned an IV, the manifest will not contain an IV
  2. when using TS container or SAMPLE-AES encryption, the module uses an IV derived from the index of the segments, no IV is returned in the manifest
  3. when using fMP4 container with AES-128 encryption, the module generates an IV using the configured seed, and returns it in the manifest

Unfortunately, these flows are quite rigid here... in our live packager (https://github.com/kaltura/media-framework/tree/master/nginx-pckg-module) I implemented it in a more flexible manner. There, you can, for example, configure explicitly whether you want to return the IV or not.

nonth commented 9 months ago

Hello @erankor

Thanks for clarifying. Just a few more questions:

  1. Is there any reason behind why the module doesn't expose IV to m3u8?
  2. Is it possible to implement something like pckg_m3u8_enc_output_iv, similar to the nginx-pckg-module for option 1? I can work on that.
erankor commented 9 months ago
  1. There just wasn't any need for this -
    • When using FairPlay DRM, the IV is served with the license
    • When using clear key with MPEG-TS, the module uses the default IV - derived from the segment index
    • When using clear key with fMP4, the module outputs the IV in the m3u8 - following a question I sent Apple long time ago :) they added this sentence to the HLS specification -
      If the Media Initialization Section declared by an EXT-X-MAP tag is
      encrypted with a METHOD of AES-128, the IV attribute of the EXT-X-KEY
      tag that applies to the EXT-X-MAP is REQUIRED.
  2. It is possible, but I didn't quite understand why you need it.
nonth commented 8 months ago

@erankor I've submitted PR #1514 regarding this issue. Could you please review it?

Thanks.