Skip to content

Content Protection with DRM

DRM (Digital Rights Management) is a content protection method where the content is encrypted and decrypted by using a pair of keys. The keys are generated by the DRM system's key server.

This page describes the settings that apply for all supportes DRM systems.

To learn how to set a certains DRM, follow these links. Flussonic Media Server supports the following DRM systems:

The mechanism of DRM

In the HLS specification Apple describes two standard encryption alorithms: AES-128 and SAMPLE-AES. Flussonic Media Server supports both algorithms, and a number of DRM systems.

The algorithms use different encryption methods, but they all work in the same way:

  1. Flussonic requests and retrieves an encryption key from a key server along with the URL of this key.
  2. The client retrieves encrypted content and the URL of a decryption key from the Flussonic server.
  3. The key server receives a request from the client and then decides whether it should respond with a decryption key or not.

If the client receives video content from Flussonic over a safe channel and connects to the key server over HTTPS, you can most likely expect that it can decrypt video and play it without revealing this decrypted content to illegitimate users.

Live streams and VOD files use the same encryption mechanism.

Setting up encryption in general

Flussonic Media Server stores all content in unencrypted form. Content gets encrypted only when Flussonic transmits it to the client.

flussonic drm

To turn on encryption, you should add the drm line to the configuration entry of a stream or VOD location. Then specify the DRM encryption method and the DRM key server.


stream channel0 {
  url fake://fake;
  drm aes128 keyserver=http://examplehost:5000/cas-server;
}

Service-specific DRM settings can be found in the relevant sections of this manual (see the links earlier on this page).

After you have saved the configuration, Flussonic will encrypt content for all protocols that can work with the specified DRM.

HLS playback options

For successful playback of an AES128 encrypted stream via HLS on some modern devices (running on Tizen 5), add the option hls_ext_x_key_iv=false:


stream channel0 {
  url fake://fake;
  drm aes128 keyserver=http://examplehost:5000/cas-server hls_ext_x_key_iv=false;
}

Prohibiting the playback via certain protocols

Danger

Make sure you disable all protocols that do not support the specified DRM. For example, if an encryption method is supported by HLS, but the HDS protocol has been left enabled, users can potentially play the video via HDS, bypassing the content protection.


stream channel0 {
  url udp://239.0.0.1:1234;
  protocols hls;
  drm aes128 keyserver=http://examplehost:5000/cas-server;
}
file vod {
  path /storage;
  protocols hls;
  drm aes128 keyserver=http://examplehost:5000/cas-server;
}

In the example above a user could only access video over HLS.

DRM for VOD files

When streaming VOD files with DRM, the external key server cannot distribute keys directly, because it does not know when a file will be opened.

To work around this problem, configure the file for accessing a key server directly:


file vod {
  path /storage;
  protocols dash hls;
  drm aes128 keyserver=http://examplehost:5000/cas-server;
}

In this configuration, Flussonic will send an HTTP GET request to the key server with a ?file= parameter when the file is accessed: http://examplehost:5000/cas-server?file=drm/bunny.mp4

As a response Flussonic expects data where the first 32 bytes should be a hexadecimal representation of an encryption key. In the response, an X-Key-Url HTTP header should be present. The header will be forwarded to the client. The X-Key-Url header should contain a 16-byte-long decryption key (NOT in hexadecimal form).

DRM protection of DVR archives

Archives are encrypted segment-by-segment with a key that rotates every 10 minutes. Every rotation, a new key is requested from the DRM server.

Caution

For DRM protection to work on the DVR archive, the key server must store all old keys (at old URLs) for a time equal to the depth of the archive.

Enabling encryption of all frames

By default, Flussonic encrypts only key frames. In most cases this is enough to protect against unauthorized access to the stream, and also reduces power consumption when decrypting on the client side. However, some Smart TVs and STBs require that all frames must be encrypted.

To enable encryption of all frames, use the encryption=full option when configuring DRM.

To enable encryption of only key frames, use the encryption=sparse option.


stream channel0 {
  url udp://239.0.0.1:1234;
  protocols dash hls;
  drm aes128 keyserver=http://examplehost:5000/cas-server encryption=full;
}

Encryption key rotation

Many DRM servers rotate license keys in order to achieve better security. By default, Flussonic does not rotate the encryption keys. To enable rotation and change the key rotation interval, use the expires option and specify the required time in minutes.


stream channel1 {
  url udp://239.0.0.1:1234;
  protocols dash hls;
  drm aes128 keyserver=http://examplehost:5000/cas-server expires=60;
}

In the case of using the expires option the drm_id is generated automatically with each new request for the encryption key.

Caution

Enabling the expires option means regularly updating encryption keys from the key server. Depending on the conditions DRM provider may charge for each key issued. We recommend to check your agreement with the DRM provider before enabling the expires option.

CPIX API

CPIX is an open specification developed by DASH-IF that provides an XML-based interoperable format for exchanging content protection configurations between different systems.

Flussonic Media Server supports the CPIX API. Now any DRM provider that supports CPIX API can integrate with Flussonic.

CPIX uses the following XML schema to describe the data used for key exchange.

Configuring CPIX DRM

To configure DRM protection with CPIX key exchange format, specify your key server with the drm cpix option.

For a stream:

stream mystream {
  url udp://239.0.0.1:1234;
  protocols dash hls mss;
  meta drm_id MYSTREAM;
  drm cpix keyserver=http://my.keyserver;
}

For a file:

file vod {
  path /storage/vod;
  protocols dash hls mss;
  meta drm_id MYSTREAM;
  drm cpix keyserver=http://my.keyserver;
}

Request example

When the stream mystream is requested, Flussonic sends a POST request to the URL http://my.keyserver with the following payload body:

<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX xmlns:cpix="urn:dashif:org:cpix" xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:speke="urn:aws:amazon:com:speke" id="MYSTREAM">
  <cpix:ContentKeyList>
    <cpix:ContentKey kid="2d70751b-972e-1479-7ef9-9fc835860120"/>
  </cpix:ContentKeyList>
  <cpix:DRMSystemList>
    <cpix:DRMSystem kid="2d70751b-972e-1479-7ef9-9fc835860120" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"/> # widevine
    <cpix:DRMSystem kid="2d70751b-972e-1479-7ef9-9fc835860120" systemId="9a04f079-9840-4286-ab92-e65be0885f95"/> # playready
    <cpix:DRMSystem kid="2d70751b-972e-1479-7ef9-9fc835860120" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2"/> # fairplay
  </cpix:DRMSystemList>
</cpix:CPIX>

The fields used in the request and response, such as ContentKeyList and DRMSystemList are described in DASH-IF Implementation Guidelines: Content Protection Information Exchange Format

Response example

Flussonic awaits the response that looks as follows:

<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX xmlns:cpix="urn:dashif:org:cpix" xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:speke="urn:aws:amazon:com:speke" id="MYSTREAM">
   <cpix:ContentKeyList>
      <cpix:ContentKey explicitIV="" kid="2d70751b-972e-1479-7ef9-9fc835860120">
         <cpix:Data>
            <pskc:Secret>
               <pskc:PlainValue>iufSFDzgKQ+6pnV88WyZnA==</pskc:PlainValue>
            </pskc:Secret>
         </cpix:Data>
      </cpix:ContentKey>
   </cpix:ContentKeyList>
   <cpix:DRMSystemList>
        <cpix:DRMSystem kid="2d70751b-972e-1479-7ef9-9fc835860120" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
            <cpix:URIExtXKey>aHR0cHM6Ly83azR5dHV4cTVkLmV4ZWN1dGUtYXBpLnVzLXdlc3QtMi5hbWF6b25hd3MuY29tL0VrZVN0YWdlL2NsaWVudC9hYmMxMjMvOThlZTU1OTYtY2QzZS1hMjBkLTE2M2EtZTM4MjQyMGM2ZWZm</cpix:URIExtXKey>
        </cpix:DRMSystem>
      <cpix:DRMSystem kid="2d70751b-972e-1479-7ef9-9fc835860120" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
         <cpix:PSSH>AAAAd3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAFcIARIQzLxOBq/7WMlQjQ4jrSMwnxoIbW92aWRvbmUiM3sia2lkIjoiekx4T0JxXC83V01sUWpRNGpyU013bnc9PSIsInRyYWNrcyI6WyJTRCJdfSoCU0Q=</cpix:PSSH>
      </cpix:DRMSystem>
      <cpix:DRMSystem kid="2d70751b-972e-1479-7ef9-9fc835860120" systemId="9a04f079-9840-4286-ab92-e65be0885f95">
         <speke:ProtectionHeader>mAIAAAEAAQCOAjwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4AQgBrADYAOAB6AFAAdQB2AHkAVgBoAFEAagBRADQAagByAFMATQB3AG4AdwA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBsADEANgBXAHYAcABrADUAVABwAFEAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APABMAEEAXwBVAFIATAA+AGgAdAB0AHAAcwA6AC8ALwBwAGwAYQB5AHIAZQBhAGQAeQAuAGUAegBkAHIAbQAuAGMAbwBtAC8AYwBlAG4AYwB5AC8AcAByAGUAYQB1AHQAaAAuAGEAcwBwAHgAPwBwAFgAPQA1ADEANAA1ADgAOQA8AC8ATABBAF8AVQBSAEwAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==</speke:ProtectionHeader>
         <cpix:PSSH>AAACuHBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAApiYAgAAAQABAI4CPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBCAGsANgA4AHoAUAB1AHYAeQBWAGgAUQBqAFEANABqAHIAUwBNAHcAbgB3AD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AGwAMQA2AFcAdgBwAGsANQBUAHAAUQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AEwAQQBfAFUAUgBMAD4AaAB0AHQAcABzADoALwAvAHAAbABhAHkAcgBlAGEAZAB5AC4AZQB6AGQAcgBtAC4AYwBvAG0ALwBjAGUAbgBjAHkALwBwAHIAZQBhAHUAdABoAC4AYQBzAHAAeAA/AHAAWAA9ADUAMQA0ADUAOAA5ADwALwBMAEEAXwBVAFIATAA+ADwALwBEAEEAVABBAD4APAAvAFcAUgBNAEgARQBBAEQARQBSAD4A</cpix:PSSH>
      </cpix:DRMSystem>
   </cpix:DRMSystemList>
</cpix:CPIX>

Flussonic-specific options you may want to know:

  • save_template — saves the keyserver response to a file.
  • dump_url — logs the requested URL.