Skip to main content

Widevine Common Encryption

Widevine Common Encryption is one of the most widespread Content Key exchange protocols. Many encryption tools and encoders (for example, Shaka Packager) 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.

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, see also PSSH article
  • SKD URI - used by FairPlay
  • Checksum - used by PlayReady

Authorization​

Instead of using an HTTP header for authentication, you have to sign each request using your signing credentials as described under Request Signing below. The signing credentials include:

  • Provider Name
  • Signing Key
  • Signing IV (initialization vector)

You can get these values from Axinom Portal, providing your Management Key:

Signing credentials on Axinom Portal

widevine-common-encryption-credentials

WidevineProtectionInfoCredentials​

Additionally, you can manage the signing credentials programmatically using the endpoint /WidevineProtectionInfoCredentials. It exposes a collection of the signing credentials sets. Initially, you have just one. But you can create a new one or change the values for the existing credentials and even delete them.

To create new singning credentials send a POST to /WidevineProtectionInfoCredentials with the following payload (the values base64-encoded):

{
"ProviderName": "sample string 1",
"SigningKey": "QEA=",
"SigningIv": "QEA="
}

This endpoint requires an authorization header - the same as described under the Key Service Management API, i.e. you will need your tenantID and managementKey.

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.

ElementDescription
content_idContent ID, base64-encoded
drm_typesRequested DRM types, possible values: WIDEVINE, FAIRPLAY, PLAYREADY. Optional. Default - Widevine only.
tracksArray of the video tracks with their respective type (=Quality Group). Supported types: AUDIO, SD, HD, UHD1,UHD2. At least one track is required.
protection_schemeProtection 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:

ElementDescription
statusStatus code. The possible values are: "OK", "SIGNATURE_FAILED", "CONTENT_ID_MISSING", "POLICY_UNKNOWN", "TRACK_TYPE_MISSING", "TRACK_TYPE_UNKNOWN", "MALFORMED_REQUEST"
content_idSame value as in the respective request.
drmList 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
tracksArray of the video tracks according to the request with their respective type (=Quality Group) and generated key information
key_idKey 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
keyGenerated Content Key as a base64-encoded byte array.
ivRandomly 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_uriAxinom DRM FairPlay License Service specific Streaming Key Delivery (SKD) URI to be included in the HLS playlist file. A string in the format skd://[KeyID]:[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
checksumPlayReady 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
psshPSSH Box for PlayReady and Widevine (not available for FairPlay). The data-field is base64-encoded. See also PSSH article.

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.

ElementDescription
requestbase64-encoded Widevine Content Key Request (the payload)
signatureA signature for the request, serving as an authentication mechanism for the Client. See Request Signing below
signerA signer name - each Tenant of the Axinom Key Service gets a Widevine Provider Name assigned that 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 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​

Encryption Schemes​

An encryption scheme can be specified with the element protection_scheme. Supported values are CENC, CBCS, CENS, CBC1. But depending on the DRM technology, it may fall back to a default value if the specified value is not supported.

Values supported for 'protection_scheme' their mapping to the DRM technologies. Defaults are in brackets.

SchemeWidevinePlayReadyFairPlay
CENC(CENC)(CENC)CBCS
CBCSCBCSCBCS(CBCS)
CENSCENSCENCCBCS
CBC1CBC1CENCCBCS

WidevineProtectionInfoConfiguration​

You can configure the behavior of the /WidevineProtectionInfo endpoint by setting configuration parameters using the /WidevineProtectionInfoConfiguration endpoint. It supports both - GET and POST. GET for reading the current values, POST - for settings the values.

This endpoint requires an authorization header - the same as described under the Key Service Management API, i.e. you will need your tenantID and managementKey.

Example payload for the endpoint '/WidevineProtectionInfoConfiguration'
{
"PlayReadyLaUrl": "https://drm-playready-licensing.axprod.net/AcquireLicense"
}

The following parameters are currently supported:

  • PlayReadyLaUrl

PlayReady License Acquisition URL for 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, it is not relevant, because the Player can use any configured License Acquisition URL. But there are some PlayReady Player implementations that rely on the License Acquisition URL delivered as a part of the PSSH Box.

To support such Players, Axinom Key Service allows configuring the License Acquisition URL.

A part of the PSSH box for PlayReady contains a PlayReady header, which contains the License Acquisition URL in the following way:

<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 unless it is 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