Set up castLabs DRMtoday secure video delivery in Wowza Streaming Engine

This article describes setting up a plugin for the castLabs DRMtoday service in Wowza Streaming Engine™ media server software. With this plugin, you can automatically deliver secured MPEG-DASH and HLS video content from your Wowza Streaming Engine media server.

The DRMtoday service provides licensing for all major DRM systems, enabling you to adopt multiple studio-recognized DRM systems from the single plugin integration. Version 3.1.0 of the DRMtoday plugin also includes key rotation support. For more, see how the DRMtoday licensing service works.

Wowza Streaming Engine 4.5.0 or later is required for this functionality.

Streaming secured content using DRMtoday


If the DRMtoday plugin for Wowza Streaming Engine is set up correctly, it automatically encrypts all content delivered from the application for which it's configured. When a player requests the stream's manifest for the first time, the Wowza Streaming Engine application becomes active, and the DRMtoday plugin ingests the Common Encryption (CENC) key pair for the application.

Stream security in error cases


You may encounter instances when the key ingestion into DRMtoday fails, for example, due to network disruptions such as limited access to the drmtoday.com domain or DRMtoday outages. In those cases, the plugin can't stop the streaming process facilitated by the Wowza Streaming Engine application.

To maintain protection in these circumstances, encryption is activated, and an error message is written to the wowzastreamingengine_error log file in [install-dir]/logs. Since DRMtoday doesn't recognize the key in this scenario, the player can't request a valid decryption key, and playback fails. This ensures that unencrypted content never leaves the Wowza media server.

Note: The first time the DRMtoday plugin is used for an application after a streaming manifest is requested, it registers the Wowza media server application for the DRMtoday merchant account it's configured for. This process can take up to one minute to be reflected in the global DRMtoday license delivery system.

Before you start


  • Ensure your Wowza Streaming Engine server has HTTPS access to fe.drmtoday.com, auth.drmtoday.com, and their staging variants fe.staging.drmtoday.com and auth.staging.drmtoday.com. Be aware that the IP addresses change with each DRMtoday deployment.
  • Create your application in Wowza Streaming Engine. Do not enable any kind of encryption yet.
  • Configure two key seeds in DRMtoday. One is used as the dt_keyseed_id and the other as the dt_ivseed_id. You can add these values from your DRMtoday dashboard under Configuration > Key seeds. See the Server-side key derivation section for more details.
  • Do not specify the streaming method applicable. Do not enable Adobe HDS, RTMP, or RTSP/RTP.

Install the DRMtoday plugin


Follow these steps to get the latest version of the plugin and add it to your Wowza Streaming Engine installation.

  1. Use your castLabs account to log in to the castLabs Download Portal.
  2. Download drmtoday-wowza-plugin-[latest-version].jar to the lib folder of your Wowza Streaming Engine installation ([install-dir]/lib). Make sure that only one version of the plugin is deployed.

Notes:

Please contact DRMtoday support, your DRMtoday technical contact, or your DRMtoday sales representative to get access to the Wowza Streaming Engine plugin.

Add the DRMtoday module


To use the DRMtoday service for secure streaming, add the following module definition to your live or VOD streaming application in Wowza Streaming Engine. See Configure modules for steps to accomplish this task.

Name Description Fully Qualified Class Name
DRMtoday DRMtoday com.castlabs.drmtoday.wowza.v2.module.ModuleDRMtoday

Configure the DRMtoday module


After adding the DRMtoday plugin to the Modules list in Wowza Streaming Engine, adjust the default settings for the plugin by adding properties to the application configuration in Wowza Streaming Engine Manager. This task can also be completed using the Application.xml.

  1. On the Applications tab in Wowza Streaming Engine Manager, click the application name in the contents panel.
     
  2. On the application details page, click the Properties tab.
     
  3. In the Quick Links bar, click Custom.
  4. In the Custom properties section, click Edit.
     
  5. For each property in the following tables, click the Add Custom Property button. Specify the indicated property settings in the Add Custom Property dialog box, then click Add.
  6. Click to Save after configuring your parameters. Then, restart the application to apply the changes.

Set required configuration parameters

If you need help with the terminology in the following tables, refer to the DRMtoday glossary in the castLabs documentation. You must log in with a DRMtoday account to access the glossary.

Path
Name
Type
Value and description
/Root/Application dt_user String The ingest API account user from the Members / Users page in DRMtoday. To minimize abuse and password leaks, create a single Wowza media server API user that gets ingest rights.
/Root/Application dt_password String The dt_user password for the API account user in DRMtoday.
/Root/Application dt_merchant String Your merchant API name at DRMtoday. You can find the API name on the My organizations page in DRMtoday.
/Root/Application dt_env String The DRMtoday environment, either STAGING or PROD.
/Root/Application dt_keyseed_id String The ID of the keyseed that's used to derive the keys. You can find this value from your DRMtoday Dashboard under Configuration > Key seeds.
 
Important: You must configure a key seed in DRMtoday for use with this property. See Server-side key derivation for more.
/Root/Application dt_ivseed_id String The ID of the keyseed that's used to derive the Initialization Vectors (IVs) for Apple FairPlay license delivery. You can find this value from your DRMtoday dashboard under Configuration > Key seeds.
 
Important: You must configure an IV seed in DRMtoday for use with this property. See Server-side key derivation for more.
/Root/Application dt_cupertino_encryption_method String Specifies one of the following encryption methods for HLS streams:
 
  • FAIRPLAY
  • AES_128 (deprecated, plugin version 1.0)
  • OMA_AES_128 (available with plugin version 2.1.0 and later, necessary to support iOS version 10 and later)
  • SAMPLE_AES
/Root/Application cupertinoEncryptionAPIBased Boolean Set to true.

Set optional configuration parameters

Path
Name
Type
Value and description
/Root/Application dt_assetid_pattern String The pattern used as the input for dt_assetid_format and
dt_variantid_format.

For example, you can use a pattern such as .*_(.*).mp4. See Asset ID patterns for more details.
/Root/Application dt_assetid_format String The format string that uses the capturing groups from the dt_assetid_pattern as input to construct the resulting assetId.

For example, you can use a format string such as asset_{cg1}, where {cg1} is replaced by the output of the first capturing group of the dt_assetid_pattern. See Asset ID patterns for more details.
/Root/Application dt_variantid_format String The format string that uses the capturing groups from the dt_assetid_pattern as input to construct the resulting variantId. See Asset ID patterns for more details.
/Root/Application dt_keyrotation Boolean Set to true to enable key rotation. The default value is false.
/Root/Application dt_keyrotation_interval Integer The default value is 3600. See Key rotation for more details.

Debug the DRMtoday module


If you need to debug the DRMtoday plugin, manually edit the log4j-config properties file for your Wowza Streaming Engine server. You can find this XML file in the conf folder of your Wowza Streaming Engine installation ([install-dir]/conf).

  1. To continue, modify the <Configuration>/<Appenders> container by adding the following section:
<RollingFile name="serverAll" fileName="${sys:com.wowza.wms.ConfigHome}/logs/wowzastreamingengine_all.log" filePattern="${sys:com.wowza.wms.ConfigHome}/logs/wowzastreamingengine_all.%d{yyyy-MM-dd}.log">
  <PatternLayout>
    <Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n</Pattern>
    <AlwaysWriteExceptions>false</AlwaysWriteExceptions>
  </PatternLayout>
  <Policies>
    <TimeBasedTriggeringPolicy />
  </Policies>
  <DefaultRolloverStrategy>
    <Delete basePath="${sys:com.wowza.wms.ConfigHome}/logs" maxDepth="1">
      <IfLastModified age="5d" />
    </Delete>
  </DefaultRolloverStrategy>
</RollingFile>
  1. Update the <Root> section in the <Configuration>/<Loggers> container, by adding:
<AppenderRef ref="serverAll" level="info"/>

Also add this line to the <Configuration>/<Loggers> container:

<Logger name="com.castlabs.drmtoday" level="info"/>

The final <Configuration>/<Loggers> container should look similar to this:

<Loggers>
  <Logger name="com.castlabs.drmtoday" level="info"/>
  <Root level="info">
    <AppenderRef ref="stdout" level="info"/>
    <AppenderRef ref="serverAccess" level="info"/>
    <AppenderRef ref="serverError" level="warn"/>
    <AppenderRef ref="serverAll" level="info"/>
    <!-- <AppenderRef ref="serverStats" level="info"/> -->
    <!-- <AppenderRef ref="vhostAccess" level="info"/> -->
    <!-- <AppenderRef ref="vhostError" level="warn"/> -->
    <!-- <AppenderRef ref="applicationAccess" level="info"/> -->
    <!-- <AppenderRef ref="applicationError" level="warn"/> -->
    <!-- <AppenderRef ref="applicationInstanceAccess" level="info"/> -->
    <!-- <AppenderRef ref="applicationInstanceError" level="warn"/> -->
  </Root>
</Loggers>

Alternatively, you can set the logger level to debug, which may generate very verbose output. For more, see Enable debug logging for Wowza Streaming Engine.

Learn more about DRMtoday configurations


Asset ID construction

The assetId used to ingest the keys to DRMtoday is derived from the channel name like this:

<wowza_application_name>_<content_file_name>

Note: DRMtoday doesn't allow the use of slashes in asset IDs. All forward slashes in the content file name are substituted with underscores.

Asset ID patterns

Some asset IDs may be too long, making them more difficult to use for authentication. In such cases, it's possible to configure a pattern matching the asset ID as it's taken from the stream name. The output of the capturing groups for this pattern can be used as the input for a format string, allowing you to construct a desired asset ID.

Note: Use the asset ID feature with care. Asset IDs should be unique for each piece of content. Otherwise, deriving the same key for two different assets can lead to cryptographic security issues.

To use the asset ID feature, configure at least the dt_assetid_pattern and the dt_assetid_format.

Capturing groups from the dt_assetid_pattern can be referenced in the dt_assetid_format string using {cg} and the capturing group number. For example, the first capturing group would be {cg1}, the second would be {cg2}, and so on.

The find method locates the pattern in the input string, matching any portion of the assetId string. You can use this site to test how Java behaves. Paste your examples and leave all options unchecked. When testing, the find() column should contain a Yes value. The last column displays the content of the capturing groups with the number that can be used in the format string.

Example usage

Let's take an example assetId of vod2_asset_pattern_sample.mp4.

  • Configure the dt_assetid_pattern to .*_(.*).mp4.
  • Configure the dt_assetid_format to format_asset_{cg1}.
  • The string sample now matches the first capturing group. The format string result is format_asset_sample.

Server-side key derivation

Starting with the DRMtoday Wowza Streaming Engine plugin version 2.0.0, key derivation is handled server side. See Key seed-based ingest for details and to learn how to configure the required key seeds in DRMtoday.

Note: When configuring the dt_keyseed_id and the dt_ivseed_id in the DRMtoday Dashboard, please copy the ID values and add them to your Wowza Streaming Engine application. The ID is the generated UUID string. Make sure you're not using the seed itself.

Here's an example of how the key seeds appear in the Application.xml for a given application:

<Property>
    <Name>dt_keyseed_id</Name>
    <Value>01234567-89ab-cdef-0123-456789abcdef</Value>
    <Type>String</Type>
</Property>
<Property>
    <Name>dt_ivseed_id</Name>
    <Value>fedcba98-7654-3210-fedc-ba9876543210</Value>
    <Type>String</Type>
</Property>

Multikey support

The DRMtoday Wowza Streaming Engine plugin supports generating multiple keys for different profiles of live content. Multikey support for VOD content is not available currently.

By default, each quality referenced in a SMIL file for adaptive live streaming is ingested to DRMtoday as an independent asset with a unique assetId and video and audio streamType.

To ingest multiple sources with the same assetId but a different streamType, source names should match the following pattern:

(.*)_ _DT_ _(UHD|HD|SD|AUDIO|VIDEO|VIDEO_AUDIO)_.*

Example usage

Let's assume that the Wowza Streaming Engine application used for live streaming is called live, and we have the following adaptive live.smil:

<?xml version="1.0" encoding="UTF-8"?>
  <smil title="Live">
    <body>
      <switch>
        <video src="live__DT__SD_.stream">
          <param name="videoBitrate" value="1024000" valuetype="data"></param>
        </video>
        <video src="live__DT__HD_.stream">
          <param name="videoBitrate" value="8192000" valuetype="data"></param>
        </video>
      </switch>
    </body>
  </smil>

With the setup in this example, DRMtoday ingests the following two entries:

  • assetId: live_live, streamType: SD, Key ID: {keyId1} → for the first entry in the SMIL file
  • assetId: live_live, streamType: HD, Key ID: {keyId2} → for the second entry in the SMIL file

Key rotation

Version 3.1.0 of the DRMtoday plugin adds support for key rotation. This enhances security and minimizes vulnerabilities by allowing you to rotate keys that encrypt content over time.

Within DRMtoday, a specific keyRotationId can be identified in addition to the assetId. It's important that this ID progresses sequentially, allowing DRMtoday to provide the existing key and subsequent key during a licensing request.

The system can look up the next key by incrementing the current keyRotationId value by one. This step is important to make sure the player transitions to the new key seamlessly, without any interruptions.

Due to this sequential requirement, the keyRotationId can't just be any increasing number. It's typically calculated by dividing the current time by a set interval. For this purpose, it's important to differentiate between a live application and a VOD application in Wowza Streaming Engine.

The next two sections describe the different key rotation considerations based on application type.

Live key rotation

For live applications, the keyRotationId is calculated by dividing the system time (in Unix epoch seconds) by the value set for the dt_keyrotation_interval. Using the system time guarantees a continuously incrementing key rotation ID, even after the Wowza Streaming Engine server is restarted.

The streaming server generates a keyRotationId roughly for every chunk duration of the video. Therefore, the dt_keyroration_interval should be equal to or greater than the chunk duration. This ensures that the calculation of the key rotation ID returns the last keyRotationId, or it's incremented by one.

The interval setting impacts the frequency of license requests to DRMtoday, so avoid setting this too low. By default, it's set to 3600 or a one-hour interval. Even if the configured value is lower, the suggested minimum for the dt_keyrotation_interval is 30 seconds. This minimum value prevents key rotation IDs that are too high and rotation intervals that are too low. The 30-second minimum should only be used for testing. In production environments, this value should be significantly higher.

VOD key rotation

In contrast, VOD applications call for the key rotation ID to be determined using the chunkId, not the system time. This ensures that every time a video begins, identical video chunks are encrypted with the same key from the start. Since the starting chunkId is zero, the first keyRotationId is also zero.

For VOD, the dt_keyrotation_interval parameter isn't directly tied to the time interval in seconds, so the chunk interval must be considered. To find the appropriate dt_keyrotation_interval value, use the following formula:

dt_keyrotation_interval = desired_interval_in_seconds / chunk_duration

Example usage

Let's assume the desired interval is 3600 seconds, and the chunk duration is 10 seconds. The dt_keyrotation_interval can be set to 360.

More resources