Widevine Common Encryption is a very widespread content key exchange protocol that can help to protect your content. See example formats of requests and responses and learn how to use it.

Widevine Common Encryption

Widevine Common Encryption is one of the most widespread Content Key exchange protocols. Many encryption tools and encoders support it.

Axinom Key Service implements Widevine Common Encryption protocol providing the endpoint /WidevineProtectionInfo of the Key Acquisition API.

See also:

Functionality

The Client requests one or more content keys. The Key Service generates the necessary keys using the Key Seed model and returns the keys with additional DRM-specific metadata where needed.

ClientKey_ServiceKey_Acquisition_APIPackager orEncryption Engine orCMS, e.g. Shaka PackagerWidevine RequestWidevine Response
Figure 1. Widevine Common Encryption - Request/Response

The Client shall send a single request for each video. If the video has multiple tracks (bitrates), different keys can be requested for each quality group (AUDIO, SD, HD, UHD1, UHD2).

The Key Service supports the following DRM technologies: Widevine, FairPlay, and PlayReady and the following protection schemes: CENC, CBC1, CENS, CBCS.

The following information is provided for each generated key:

  • Key ID - can be set by the Client or randomly generated by the Key Service

  • Key value - generated by the Key Service based on the default Key Seed

  • IV - random initialization vector, needed for FairPlay

  • PSSH Box - can be used by encoder to add to the output stream

  • SKD URI - used by FairPlay

  • Checksum - used by PlayReady

Request/Response Format

Widevine Content Key Request

The Client provides the input parameters in a JSON data structure called the Widevine Content Key Request:

{
  "content_id": "MEIzNTBDMDgtNEJDQi00Qjk2LUE4NzMtOEMyNEY2RTk5MUM1",
  "drm_types": [
    "WIDEVINE",
    "PLAYREADY",
    "FAIRPLAY"
  ],
  "tracks": [
    {"type": "AUDIO"},
    {"type": "SD"},
    {"type": "HD"},
    {"type": "UHD1"},
    {"type": "UHD2"}
  ],
  "protection_scheme": "CENC"
}

The table below outlines the elements of the Content Key request JSON above.

Element Description

"content_id"

Content ID, base64-encoded.

"drm_types"

Requested DRM types, possible values: WIDEVINE, FAIRPLAY, PLAYREADY. Optional. Default - Widevine only.

"tracks"

Array of the video tracks with their respective type (=Quality Group). Supported types: AUDIO, SD, HD, UHD1, UHD2. At least one track is required.

"protection_scheme"

Protection scheme to use. Supported values: CENC, CBC1, CENS, CBCS. Optional. Default - CENC.

The Content ID can be:

  • A GUID, presented as a string in the format 00000000-0000-0000-0000-000000000000. In this case, all tracks have the same Content Key. Its Key ID matches the provided Content ID.

  • Any string, prefixed with "CID:", e.g. "CID:Batman". In this case, every track has its own Content Key with a random Key ID.

Widevine Content Key Response

The Key Service provides a response as a JSON data structure called the Widevine Content Key Response. It is very similar to the Widevine Content Key Request, but it is extended with the generated key material:

{
	"status": "OK",
	"content_id": "MEIzNTBDMDgtNEJDQi00Qjk2LUE4NzMtOEMyNEY2RTk5MUM1",
	"drm": [
		{"type": "WIDEVINE", "system_id": "edef8ba979d64acea3c827dcd51d21ed"},
		{"type": "PLAYREADY", "system_id": "9a04f07998404286ab92e65be0885f95"},
		{"type": "FAIRPLAY", "system_id": "29701fe43cc74a348c5bae90c7439a47"}
	],
	"tracks": [
        ...
		{
			"type": "HD",
			"key_id": "CzUMCEvLS5aoc4wk9umRxQ==",
			"key": "xL/zgE8V9fjPEdqQse5NIA==",
			"iv": "Bc2m8UG/rpC/eTDuacmtSw==",
			"skd_uri": "skd://0b350c08-4bcb-4b96-a873-8c24f6e991c5:05CDA6F141BFAE90BF7930EE69C9AD4B",
			"checksum": "jmiyKlynsq4=",
			"pssh": [
				{"drm_type": "WIDEVINE", "data": "EhAL...WbBg=="},
				{"drm_type": "PLAYREADY", "data": "xAE...gA="},
				{"drm_type": "FAIRPLAY", "data": ""}
			]
		},
        ...
    ]
}

The table below explains the elements of the Content Key response JSON.

Element Description

"status"

Status code. The possible values are: "OK", "SIGNATURE_FAILED", "CONTENT_ID_MISSING", "POLICY_UNKNOWN", "TRACK_TYPE_MISSING", "TRACK_TYPE_UNKNOWN", "MALFORMED_REQUEST".

"content_id"

Same value as in the respective request.

"drm"

List of the DRM systems for which the keys are generated according to the request. Contains a type and a system_id (GUID) for each DRM.

"tracks"

Array of the video tracks according to the request with their respective type (=Quality Group) and generated key information.

"key_id"

Key ID of the Content Key, base64-encoded GUID, serialized as a byte array in a big endian byte order. For example, the following byte array - 0B350C084BCB4B96A8738C24F6E991C5 - shall result in the following GUID: 0B350C08-4BCB-4B96-A873-8C24F6E991C5. If the content_id is a GUID, all key_ids are equal to it. Otherwise, all key_ids are different and random.

"key"

Generated Content Key as a base64-encoded byte array.

"iv"

Randomly generated Initialization Vector (IV) for the Content Key. An explicit IV is generated only for FairPlay, but even for FairPlay the IV can be generated by the encoder, thus overriding this IV.

"skd_uri"

Axinom DRM FairPlay License Service specific Streaming Key Delivery (SKD) URI to be included in the HLS playlist file. A string in the format skd://[Key ID]:[IV] where [Key ID] is a GUID in its string representation and [IV] is a 16-byte array in hex encoding. This field is only generated if FairPlay is requested. Additionally, the :[IV] part of the SKD URI may be omitted when using the Axinom DRM License Service for License Acquisition.

"checksum"

PlayReady Content Key ID/Content Key checksum, as an 8-byte array in base64 encoding. This field is only generated if PlayReady is requested, but it doesn’t have to be used, not even for PlayReady

"pssh"

PSSH Box for PlayReady and Widevine (not available for FairPlay). The data-field is base64-encoded.

Envelope

Before the Widevine Content Key Request goes on the wire, it shall be wrapped in an "envelope" - a JSON data structure called Widevine Request:

{
    "request": "eyJjb250ZW50X2lkIjoiTUVJek5UQkRNRGd0TkVKRFFpMDBRamsyTFVFNE56TXRPRU15TkVZMlJUazVNVU0xIiwidHJhY2tzIjpbeyJ0eXBlIjoiQVVESU8ifSx7InR5cGUiOiJTRCJ9LHsidHlwZSI6IkhEIn1dfQ==",
    "signature": "kpn8s1kS0GVexoCRz1vc6Bxn833Y2wEQDZofugGpcDU=",
    "signer": "widevine_test"
}

The elements of the JSON envelope are described in the table below.

Element Description

"request"

base64-encoded Widevine Content Key Request (the payload)

"signature"

A signature for the request, serving as an authentication mechanism for the Client. See Request Signing below.

"signer"

A signer name - each Tenant of the Axinom Key Service gets a Widevine Provider Name assigned which shall be used as a Signer.

The Key Service response - the Widevine Content Key Response - is wrapped into a JSON data structure called the Widevine Response:

{
    "response": "eyJzdGF0dXMiOiJPSyIsImNvbnRlbnRfaWQiOiIwQjM1MEMwOC00QkNCLTRCOTYtQTg3My04QzI0RjZFOTkxQzUiLCJkcm0iOlt7InR5cGUiOiJXSURFVklORSIsInN5c3RlbV9pZCI6ImVkZWY4YmE5LTc5ZDYtNGFjZS1hM2M4LTI3ZGNkNTFkMjFlZCJ9XSwidHJhY2tzIjpbeyJwc3NoIjpbeyJkcm1fdHlwZSI6IldJREVWSU5FIiwiZGF0YSI6IkNBRVNFQXMxREFoTHkwdVdxSE9NSlBicGtjVWFEWGRwWkdWMmFXNWxYM1JsYzNRaUpEQkNNelV3UXpBNExUUkNRMEl0TkVJNU5pMUJPRGN6TFRoRE1qUkdOa1U1T1RGRE5Tb0ZRVlZFU1U4PSJ9XSwia2V5X2lkIjoiQ3pVTUNFdkxTNWFvYzR3azl1bVJ4UT09IiwidHlwZSI6IkFVRElPIiwia2V5IjoieEwvemdFOFY5ZmpQRWRxUXNlNU5JQT09In0seyJwc3NoIjpbeyJkcm1fdHlwZSI6IldJREVWSU5FIiwiZGF0YSI6IkNBRVNFQXMxREFoTHkwdVdxSE9NSlBicGtjVWFEWGRwWkdWMmFXNWxYM1JsYzNRaUpEQkNNelV3UXpBNExUUkNRMEl0TkVJNU5pMUJPRGN6TFRoRE1qUkdOa1U1T1RGRE5Tb0NVMFE9In1dLCJrZXlfaWQiOiJDelVNQ0V2TFM1YW9jNHdrOXVtUnhRPT0iLCJ0eXBlIjoiU0QiLCJrZXkiOiJ4TC96Z0U4VjlmalBFZHFRc2U1TklBPT0ifSx7InBzc2giOlt7ImRybV90eXBlIjoiV0lERVZJTkUiLCJkYXRhIjoiQ0FFU0VBczFEQWhMeTB1V3FIT01KUGJwa2NVYURYZHBaR1YyYVc1bFgzUmxjM1FpSkRCQ016VXdRekE0TFRSQ1EwSXRORUk1TmkxQk9EY3pMVGhETWpSR05rVTVPVEZETlNvQ1NFUT0ifV0sImtleV9pZCI6IkN6VU1DRXZMUzVhb2M0d2s5dW1SeFE9PSIsInR5cGUiOiJIRCIsImtleSI6InhML3pnRThWOWZqUEVkcVFzZTVOSUE9PSJ9XX0="
}
Note
The "response" is a base64-encoded Widevine Content Key Response (the payload).
Widevine RequestrequestsignaturesignerWidevine Content Key Requestcontent_iddrm_typestracksprotection_schemeWidevine ResponseWidevine Content Key Responsestatuscontent_iddrmtracksTracktypekey_idkeyivskd_urichecksumpsshrequestresponsetracks
Figure 2. Widevine Common Encryption - Data Model

Request Signing

To calculate the signature:

  • Compute the SHA1-hash of the Widevine Content Key Request (before applying base64 to it).

  • Encrypt the calculated SHA1-hash using AES-CBC using a 32-byte key and a 16-byte IV. Each Tenant of the Axinom Key Service gets a Widevine Signing Key and Widevine Signing IV assigned for this purpose.

  • Apply base64-encode

Resources

  • Online tool for signing and executing Widevine Common Encryption requests: Click here

  • Code sample in C#

  • Code sample in JavaScript (GenerateKeyUsingKeyServer.js), available as a part of the Quick Start Guide (Click here)

Configuring the PSSH Box

PSSH Box included in the protected video contains some metadata about the applied protection. A part of this data structure is a License Acquisition URL. In most cases, this is not important, because the Player can use any configured License Acquisition URL. But there are some PlayReady Player implementations which rely on the License Acquisition URL delivered as a part of the PSSH Box.

To support such Players, Axinom Key Service allows to configure the License Acquisition URL, which is included in the PlayReady PSSH Box. To set the URL, use the following call:

POST {keyServiceURL}}/api/WidvineProtectionInfoConfiguration
Authorization: Basic {{tenantID}}:{{managementAPIKey}}

{
  "PlayReadyLaUrl": "https://drm-playready-licensing.axprod.net/AcquireLicense"
}

A part of the PSSH Box for PlayReady contains a PlayReady header, which contains the License Acquisition URL.

<WRMHEADER xmlns="https://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader" version="4.0.0.0">
  <DATA>
    <PROTECTINFO>
      <ALGID>AESCTR</ALGID>
      <KEYLEN>16</KEYLEN>
    </PROTECTINFO>
    <KID>q5HgCTj40kGeNVhTH9Gexw==</KID>
    <LA_URL>https://drm-playready-licensing.axprod.net/AcquireLicense</LA_URL>
  </DATA>
</WRMHEADER>
Note
LA_URL is not present if it is not previously set using the /WidevineProtectionInfoConfiguration endpoint.

To read more about PlayReady headers, follow this link: https://docs.microsoft.com/en-us/playready/specifications/playready-header-specification.

Putting it all Together

Below are the steps to get a key from the Axinom Key Service using the Widevine Common Encryption protocol.

We assume here that:

  • the Content ID is "CID:Batman"

  • there are 3 tracks: Audio, SD, and HD

  • each track will be protected with its own content key

  • only Widevine is in use

  • a default protection scheme is applicable

    1. Create a Widevine Content Key Request:

      {
        "content_id": "Q0lEOkJhdG1hbg==",
        "tracks": [
          {"type": "AUDIO"},
          {"type": "SD"},
          {"type": "HD"}
        ]
      }
    2. Calculate the signature as described in Request Signing above.

    3. Compose the Widevine Request:

      {
        "request": "<base64(Widevine Content Key Request)>",
        "signature": "<Calculated Signature(Widevine Content Key Request, Widevine Signing Key, Widevine Signing IV)>",
        "signer": "<Widevine Provider Name>"
      }
    4. Send the Widevine Request to the Axinom Key Service:

      POST <Key Service API>/api/WidevineProtectionInfo
      <Widevine Request>
    5. If everything is done correctly, you get a Widevine Response with an HTTP code 200:

      {
        "response": "<Widevine Content Key Response as base64>"
      }
    6. Base64-decode the response.

    7. For each track, extract the key_id and key elements and base64-decode them.

The online-tools under My DRM will help you.

Differences Between Axinom and Google Implementations

Google provides its own implementation of the Widevine Common Encryption protocol in the Widevine Cloud Service.

There are a few differences with the Axinom implementation:

  1. Google Service supports only Widevine

  2. Axinom uses the Key Seed Model

  3. Axinom applies a naming convention for the content_id (see above)

  4. Google Service supports some additional features

Revision History

The table below lists the document versions and any changes to them.

Version Date Description

1.0

November 20, 2020

  • Initial version

1.1

May 20, 2021

  • Comments in code replaced by tables.