Encryption Key Provision (Standalone)

CPIX API

We highly recommend using the CPIX API to fetch Studio DRM encryption keys in CPIX XML document format.

This API can also be used to return the keys from the CPIX document in JSON format; for more information on this please see the JSON keys section.

All requests made to this API will require your API key set as the header API-KEY. If you do not know or have not been given your API key please contact JW Player Support.


Retrieve all DRM systems

https://cpix.vudrm.tech/v1/cpix/{client}/{content_id}
Retrieves a CPIX 2.1 document with all DRM systems the specified client is entitled to use


Request

curl -X GET 'https://cpix.vudrm.tech/v1/cpix/{client}/{content_id}' \
     -H 'API-KEY: {api_key}'

Path Parameters

Parameter Description
client Client name
content_id Unique identifier for the content

The content_id may only contain alphanumeric characters, underscores, and hyphens.

Query Parameters

Parameter Description
drm Comma-delimited list of DRM systems to be included in the response

Possible values:
Β Β Β β€’ fairplay
Β Β Β β€’ playready
Β Β Β β€’ widevine
Response
<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:xsi="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:cpix="urn:dashif:org:cpix" xsi:schemaLocation="urn:dashif:org:cpix cpix.xsd">
  <cpix:ContentKeyList>
    <cpix:ContentKey kid="11111111-1111-1111-1111-111111111111" explicitIV="YmFzZTY0ZW5jb2RlZAo=">
      <cpix:Data>
        <pskc:Secret>
          <pskc:PlainValue>YmFzZTY0ZW5jb2RlZAo=</pskc:PlainValue>
        </pskc:Secret>
      </cpix:Data>
    </cpix:ContentKey>
  </cpix:ContentKeyList>
  <cpix:DRMSystemList>
    <cpix:DRMSystem kid="11111111-1111-1111-1111-111111111111" systemId="9a04f079-9840-4286-ab92-e65be0885f95">
      <cpix:PSSH>YmFzZTY0ZW5jb2RlZAo=</cpix:PSSH>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="11111111-1111-1111-1111-111111111111" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
      <cpix:PSSH>YmFzZTY0ZW5jb2RlZAo=</cpix:PSSH>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="11111111-1111-1111-1111-111111111111" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
      <cpix:URIExtXKey>YmFzZTY0ZW5jb2RlZAo=</cpix:URIExtXKey>
      <cpix:HLSSignalingData playlist="master">YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
<cpix:HLSSignalingData playlist="media">YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
    </cpix:DRMSystem>
  </cpix:DRMSystemList>
</cpix:CPIX>




Retrieve a single content key

https://cpix.vudrm.tech/v1/cpix/{client}/{content_id}/decrypt
Retrieves a CPIX 2.1 document with only a single content key


Request

curl -X GET 'https://cpix.vudrm.tech/v1/cpix/{client}/{content_id}/decrypt' \
     -H 'API-KEY: {api_key}'

Path Parameters

Parameter Description
client Client name
content_id Unique identifier for the content

The content_id may only contain alphanumeric characters, underscores, and hyphens.

Query Parameters

Parameter Description
drm Comma-delimited list of DRM systems to be included in the response

Possible values:
Β Β Β β€’ fairplay
Β Β Β β€’ playready
Β Β Β β€’ widevine
Response
<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:xsi="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:cpix="urn:dashif:org:cpix" xsi:schemaLocation="urn:dashif:org:cpix cpix.xsd">
  <cpix:ContentKeyList>
    <cpix:ContentKey kid="11111111-1111-1111-1111-111111111111" explicitIV="YmFzZTY0ZW5jb2RlZAo=">
      <cpix:Data>
        <pskc:Secret>
          <pskc:PlainValue>YmFzZTY0ZW5jb2RlZAo=</pskc:PlainValue>
        </pskc:Secret>
      </cpix:Data>
    </cpix:ContentKey>
  </cpix:ContentKeyList>
</cpix:CPIX>



Retrieve document using video and audio track content keys

https://cpix.vudrm.tech/v1/cpix/{client}/{content_id}/multikey
Retrieves a CPIX 2.1 document that uses separate keys for video and audio tracks


Request

curl -X GET 'https://cpix.vudrm.tech/v1/cpix/{client}/{content_id}/multikey' \
     -H 'API-KEY: {api_key}'

Path Parameters

Parameter Description
client Client name
content_id Unique identifier for the content

The content_id may only contain alphanumeric characters, underscores, and hyphens.

Query Parameters

Parameter Description
bitrates Single bitrate, or two separated by a comma

If provided with a single bitrate the document will use one key for all bitrates up to the given bitrate, and one key for the given bitrate up.

If provided with two bitrates the document will use one key for all bitrates up to the lowest given bitrate, one key for all bitrates between the lowest and highest bitrates, and one key for the highest given bitrate up.

If both bitrates and videoTracks are included in the API request, videoTracks will be ignored by the API.
drm Comma-delimited list of DRM systems to be included in the response

Possible values:
Β Β Β β€’ fairplay
Β Β Β β€’ playready
Β Β Β β€’ widevine
videoTracks List of video qualities separated by a comma

Possible values:
Β Β Β β€’ HD
Β Β Β β€’ SD
Β Β Β β€’ UHD

If provided with multiple video qualities the response will contain an encryption key for each video quality and one encryption key for everything else.

If both bitrates and videoTracks are included in the API request, videoTracks will be ignored by the API.
Response
<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:xsi="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:cpix="urn:dashif:org:cpix" xsi:schemaLocation="urn:dashif:org:cpix cpix.xsd">
  <cpix:ContentKeyList>
    <cpix:ContentKey kid="11111111-1111-1111-1111-111111111111" explicitIV="YmFzZTY0ZW5jb2RlZAo=">
      <cpix:Data>
        <pskc:Secret>
          <pskc:PlainValue>YmFzZTY0ZW5jb2RlZAo=</pskc:PlainValue>
        </pskc:Secret>
      </cpix:Data>
    </cpix:ContentKey>
    <cpix:ContentKey kid="22222222-2222-2222-22222-22222222222" explicitIV="YmFzZTY0ZW5jb2RlZAo=">
      <cpix:Data>
        <pskc:Secret>
          <pskc:PlainValue>YmFzZTY0ZW5jb2RlZAo=</pskc:PlainValue>
        </pskc:Secret>
      </cpix:Data>
    </cpix:ContentKey>
  </cpix:ContentKeyList>
  <cpix:DRMSystemList>
    <cpix:DRMSystem kid="11111111-1111-1111-1111-111111111111" systemId="9a04f079-9840-4286-ab92-e65be0885f95">
      <cpix:PSSH>YmFzZTY0ZW5jb2RlZAo=</cpix:PSSH>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="11111111-1111-1111-1111-111111111111" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
      <cpix:PSSH>YmFzZTY0ZW5jb2RlZAo=</cpix:PSSH>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="11111111-1111-1111-1111-111111111111" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
      <cpix:URIExtXKey>YmFzZTY0ZW5jb2RlZAo=</cpix:URIExtXKey>
      <cpix:HLSSignalingData playlist="master">YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
      <cpix:HLSSignalingData playlist="media">YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="22222222-2222-2222-22222-22222222222" systemId="9a04f079-9840-4286-ab92-e65be0885f95">
      <cpix:PSSH>YmFzZTY0ZW5jb2RlZAo=</cpix:PSSH>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="22222222-2222-2222-22222-22222222222" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
      <cpix:PSSH>YmFzZTY0ZW5jb2RlZAo=</cpix:PSSH>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="22222222-2222-2222-22222-22222222222" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
      <cpix:URIExtXKey>YmFzZTY0ZW5jb2RlZAo=</cpix:URIExtXKey>
      <cpix:HLSSignalingData playlist="master">YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
      <cpix:HLSSignalingData playlist="media">YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
    </cpix:DRMSystem>
  </cpix:DRMSystemList>
  <cpix:ContentKeyUsageRuleList>
    <cpix:ContentKeyUsageRule kid="11111111-1111-1111-1111-111111111111">
      <cpix:VideoFilter></cpix:VideoFilter>
    </cpix:ContentKeyUsageRule>
    <cpix:ContentKeyUsageRule kid="22222222-2222-2222-22222-22222222222">
      <cpix:AudioFilter></cpix:AudioFilter>
    </cpix:ContentKeyUsageRule>
  </cpix:ContentKeyUsageRuleList>
</cpix:CPIX>



Retrieve document using one video content key

https://cpix.vudrm.tech/v1/cpix/{client}/{content_id}/multikey/audioclear
Retrieves a CPIX 2.1 document that uses only 1 content key for video; audio tracks are left in the clear


Request

curl -X GET 'https://cpix.vudrm.tech/v1/cpix/{client}/{content_id}/multikey/audioclear' \
     -H 'API-KEY: {api_key}'

Path Parameters

Parameter Description
client Client name
content_id Unique identifier for the content

The content_id may only contain alphanumeric characters, underscores, and hyphens.

Query Parameters

Parameter Description
drm Comma-delimited list of DRM systems to be included in the response

Possible values:
Β Β Β β€’ fairplay
Β Β Β β€’ playready
Β Β Β β€’ widevine
Response
<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:xsi="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:cpix="urn:dashif:org:cpix" xsi:schemaLocation="urn:dashif:org:cpix cpix.xsd">
  <cpix:ContentKeyList>
    <cpix:ContentKey kid="11111111-1111-1111-1111-111111111111" explicitIV="YmFzZTY0ZW5jb2RlZAo=">
      <cpix:Data>
        <pskc:Secret>
          <pskc:PlainValue>YmFzZTY0ZW5jb2RlZAo=</pskc:PlainValue>
        </pskc:Secret>
      </cpix:Data>
    </cpix:ContentKey>
    <cpix:ContentKey kid="22222222-2222-2222-22222-22222222222">
    </cpix:ContentKey>
  </cpix:ContentKeyList>
  <cpix:DRMSystemList>
    <cpix:DRMSystem kid="11111111-1111-1111-1111-111111111111" systemId="9a04f079-9840-4286-ab92-e65be0885f95">
      <cpix:PSSH>YmFzZTY0ZW5jb2RlZAo=</cpix:PSSH>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="11111111-1111-1111-1111-111111111111" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
      <cpix:PSSH>YmFzZTY0ZW5jb2RlZAo=</cpix:PSSH>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="11111111-1111-1111-1111-111111111111" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
      <cpix:URIExtXKey>YmFzZTY0ZW5jb2RlZAo=</cpix:URIExtXKey>
      <cpix:HLSSignalingData playlist="master">YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
      <cpix:HLSSignalingData playlist="media">YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="22222222-2222-2222-22222-22222222222" systemId="9a04f079-9840-4286-ab92-e65be0885f95">
      <cpix:PSSH>YmFzZTY0ZW5jb2RlZAo=</cpix:PSSH>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="22222222-2222-2222-22222-22222222222" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
      <cpix:PSSH>YmFzZTY0ZW5jb2RlZAo=</cpix:PSSH>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="22222222-2222-2222-22222-22222222222" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
      <cpix:URIExtXKey>YmFzZTY0ZW5jb2RlZAo=</cpix:URIExtXKey>
      <cpix:HLSSignalingData playlist="master">YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
      <cpix:HLSSignalingData playlist="media">YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
    </cpix:DRMSystem>
  </cpix:DRMSystemList>
  <cpix:ContentKeyUsageRuleList>
    <cpix:ContentKeyUsageRule kid="11111111-1111-1111-1111-111111111111">
      <cpix:VideoFilter></cpix:VideoFilter>
    </cpix:ContentKeyUsageRule>
    <cpix:ContentKeyUsageRule kid="22222222-2222-2222-22222-22222222222">
      <cpix:AudioFilter></cpix:AudioFilter>
    </cpix:ContentKeyUsageRule>
  </cpix:ContentKeyUsageRuleList>
</cpix:CPIX>



Rotate Fairplay keys

https://cpix.vudrm.tech/v1/cpix/{client}/{content_id}/rotate
(HLS with Fairplay only) Retrieves a CPIX 2.1 document with Fairplay keys at every given interval between two given times

πŸ“˜

USP Support: Key rotation works with USP versions 1.10.12 and 1.10.18. If you wish to use version 1.9.5, the explicitIV needs to be removed from each content key before the CPIX document is used. This can be done with the following command if the CPIX document has been stored in a file named keys.cpix.

sed -i -E 's/ explicitIV=.*"//' keys.cpix


Request

curl -X GET 'https://cpix.vudrm.tech/v1/cpix/{client}/{content_id}/rotate?start=1970-01-01T00:00:00Z&end=1970-01-01T01:00:00Z&interval=3600' \
     -H 'API-KEY: {api_key}'

Path Parameters

Parameter Description
client Client name
content_id Unique identifier for the content

The content_id may only contain alphanumeric characters, underscores, and hyphens.

Query Parameters

Parameter Description
end (Required) End time in `yyyy-MM-ddThh-mm-ssZ` format

For example:
1970-01-01T01:00:00Z
interval (Required) Interval each key should last in seconds
start (Required) Start time in `yyyy-MM-ddThh-mm-ssZ` format

For example:
1970-01-01T00:00:00Z
drm Comma-delimited list of DRM systems to be included in the response

Possible value:
Β Β Β β€’ fairplay
Response
<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:xsi="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:cpix="urn:dashif:org:cpix" xmlns:speke="urn:aws:amazon:com:speke" xsi:schemaLocation="urn:dashif:org:cpix cpix.xsd">
  <cpix:ContentKeyList>
    <cpix:ContentKey kid="11111111-1111-1111-1111-111111111111" explicitIV="YmFzZTY0ZW5jb2RlZAo=">
      <cpix:Data>
        <pskc:Secret>
          <pskc:PlainValue>YmFzZTY0ZW5jb2RlZAo=</pskc:PlainValue>
        </pskc:Secret>
      </cpix:Data>
    </cpix:ContentKey>
    <cpix:ContentKey kid="22222222-2222-2222-22222-22222222222" explicitIV="YjIxZmRlNzI5MDUyMDEzYw==">
      <cpix:Data>
        <pskc:Secret>
          <pskc:PlainValue>YmFzZTY0ZW5jb2RlZAo=</pskc:PlainValue>
        </pskc:Secret>
      </cpix:Data>
    </cpix:ContentKey>
    <cpix:ContentKey kid="33333333-3333-3333-3333-333333333333" explicitIV="YmFzZTY0ZW5jb2RlZAo=">
      <cpix:Data>
        <pskc:Secret>
          <pskc:PlainValue>YmFzZTY0ZW5jb2RlZAo=</pskc:PlainValue>
        </pskc:Secret>
      </cpix:Data>
    </cpix:ContentKey>
  </cpix:ContentKeyList>
  <cpix:DRMSystemList>
    <cpix:DRMSystem kid="11111111-1111-1111-1111-111111111111" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
      <cpix:URIExtXKey>YmFzZTY0ZW5jb2RlZAo=</cpix:URIExtXKey>
      <cpix:HLSSignalingData>YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="22222222-2222-2222-22222-22222222222" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
      <cpix:URIExtXKey>YmFzZTY0ZW5jb2RlZAo=</cpix:URIExtXKey>
      <cpix:HLSSignalingData>YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
    </cpix:DRMSystem>
    <cpix:DRMSystem kid="33333333-3333-3333-3333-333333333333" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
      <cpix:URIExtXKey>YmFzZTY0ZW5jb2RlZAo=</cpix:URIExtXKey>
      <cpix:HLSSignalingData>YmFzZTY0ZW5jb2RlZAo=</cpix:HLSSignalingData>
    </cpix:DRMSystem>
  </cpix:DRMSystemList>
  <cpix:ContentKeyPeriodList>
    <cpix:ContentKeyPeriod id="period_0" start="1970-01-01T00:00:00Z" end="1970-01-01T00:30:00Z"></cpix:ContentKeyPeriod>
    <cpix:ContentKeyPeriod id="period_1" start="1970-01-01T00:30:00Z" end="1970-01-01T01:00:00Z"></cpix:ContentKeyPeriod>
    <cpix:ContentKeyPeriod id="period_2" start="1970-01-01T01:00:00Z" end="1970-01-01T01:30:00Z"></cpix:ContentKeyPeriod>
  </cpix:ContentKeyPeriodList>
  <cpix:ContentKeyUsageRuleList>
    <cpix:ContentKeyUsageRule kid="11111111-1111-1111-1111-111111111111">
      <cpix:KeyPeriodFilter periodId="period_0"></cpix:KeyPeriodFilter>
    </cpix:ContentKeyUsageRule>
    <cpix:ContentKeyUsageRule kid="22222222-2222-2222-22222-22222222222">
      <cpix:KeyPeriodFilter periodId="period_1"></cpix:KeyPeriodFilter>
    </cpix:ContentKeyUsageRule>
    <cpix:ContentKeyUsageRule kid="33333333-3333-3333-3333-333333333333">
      <cpix:KeyPeriodFilter periodId="period_2"></cpix:KeyPeriodFilter>
    </cpix:ContentKeyUsageRule>
  </cpix:ContentKeyUsageRuleList>
</cpix:CPIX>



Retrieve encryption keys as JSON

https://cpix.vudrm.tech/v1/keys/{client}/{content_id}/
Retrieves encryption keys and license URLs for a given content_id as JSON


Request

curl -X GET 'https://cpix.vudrm.tech/v1/keys/{client}/{content_id}' \
     -H 'API-KEY: {api_key}'

Path Parameters

Parameter Description
client Client name
content_id Unique identifier for the content

The content_id may only contain alphanumeric characters, underscores, and hyphens.
Response
{
  "key_id_hex": "76616c7565686578666f726d61746564",
  "content_key_hex": "76616c7565686578666f726d61746564",
  "iv_hex": "76616c7565686578666f726d61746564",
  "playready_pssh_data": "YmFzZTY0LXBsYXlyZWFkeS1oZWFkZXItb2JqZWN0Cg==",
  "playready_system_id": "9a04f079-9840-4286-ab92-e65be0885f95",
  "widevine_drm_specific_data": "YmFzZTY0LXdpZGV2aW5lLXBzc2gtZGF0YQo=",
  "widevine_drm_specific_data_with_key_id": "YmFzZTY0LXdpZGV2aW5lLXBzc2gtZGF0YQo=",
  "widevine_system_id": "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",
  "fairplay_system_id": "94ce86fb-07ff-4f43-adb8-93d2fa968ca2",
  "fairplay_laurl": "skd://fairplay-license.vudrm.tech/license/<content-id>",
}

Response Parameters

Parameter Description
content_key_hex (FairPlay, PlayReady, Widevine) 128-bit encryption key in base16 in Little Endian
fairplay_laurl Fairplay license URL
fairplay_system_id DASH protection system-specific identifier for FairPlay
iv_hex (FairPlay) Encryption key
key_id_hex (PlayReady, Widevine) Unique ID for the encryption in base16 in Little Endian
playready_pssh_data Base64-encoded pssh data containing the PlayReady header
playready_system_id DASH protection system-specific identifier for PlayReady
widevine_drm_specific_data Base64-encoded pssh data containing the content ID
widevine_drm_specific_data_with_key_id Base64-encoded pssh data containing the content ID and the key ID
widevine_system_id The DASH protection system-specific identifier for Widevine



SPEKE Key Provider API

SPEKE Key Provider API has a SPEKE endpoint for use with AWS Media Services, please see our AWS Media Services with Studio DRM’s SPEKE API guide on how to use this API.

You can call this API directly, to do this you must set your API key as the header API-KEY. If you do not know or have not been given your API key please contact JW Player Support.


Retrieve DRM information

https://speke.vudrm.tech/{client}/speke
Retrieves DRM information formatted to the AWS SPEKE standard


Request

curl -X POST 'https://speke.vudrm.tech//{client}/speke' \
     -H 'API-KEY: {api_key}' \
     -H 'Content-Type: application/xml' \
     -d '<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX id="someContentId" xmlns:cpix="urn:dashif:org:cpix" xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:speke="urn:aws:amazon:com:speke">
   <cpix:ContentKeyList>
      <cpix:ContentKey kid="" explicitIV=""/>
   </cpix:ContentKeyList>
   <cpix:DRMSystemList>
      <!-- fairplay -->
      <cpix:DRMSystem kid="" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
      </cpix:DRMSystem>
   </cpix:DRMSystemList>
</cpix:CPIX>'
curl -X POST 'https://speke.vudrm.tech//{client}/speke' \
     -H 'API-KEY: {api_key}' \
     -H 'Content-Type: application/xml' \
     -d '<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX id="someContentId" xmlns:cpix="urn:dashif:org:cpix" xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:speke="urn:aws:amazon:com:speke">
   <cpix:ContentKeyList>
      <cpix:ContentKey kid="" explicitIV=""/>
   </cpix:ContentKeyList>
   <cpix:DRMSystemList>
      <!-- playready -->
      <cpix:DRMSystem kid="" systemId="9a04f079-9840-4286-ab92-e65be0885f95"> 
      </cpix:DRMSystem>
      <!-- widevine -->
      <cpix:DRMSystem kid="" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
      </cpix:DRMSystem>
   </cpix:DRMSystemList>
</cpix:CPIX>'

Path Parameter

Parameter Description
client Client name

Body Parameter

Parameter Description
--- Empty AWS SPEKE CPIX document containing the keys and other information the user wants
Response
<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX id="someContentId" xmlns:cpix="urn:dashif:org:cpix" xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:speke="urn:aws:amazon:com:speke">
    <cpix:ContentKeyList>
        <cpix:ContentKey explicitIV="fairplayIvHex-base64-encoded" kid="someKid">
            <cpix:Data>
                <pskc:Secret>
                    <pskc:PlainValue>fairplayKeyHex-base64-encoded</pskc:PlainValue>
                </pskc:Secret>
            </cpix:Data>
        </cpix:ContentKey>
    </cpix:ContentKeyList>
    <cpix:DRMSystemList>
        <cpix:DRMSystem kid="someKid" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
            <URIExtXKey>fairplayLaurl-base64-encoded</URIExtXKey>
            <KeyFormat>fairplayKeyFormat-base64-encoded</KeyFormat>
            <KeyFormatVersions>fairplayKeyFormatVersion-base64-encoded</KeyFormatVersions>
        </cpix:DRMSystem>
    </cpix:DRMSystemList>
</cpix:CPIX>
<?xml version="1.0" encoding="UTF-8"?>
<cpix:CPIX id="someContentId" xmlns:cpix="urn:dashif:org:cpix" xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:speke="urn:aws:amazon:com:speke">
    <cpix:ContentKeyList>
        <cpix:ContentKey explicitIV="" kid="someKid">
            <cpix:Data>
                <pskc:Secret>
                    <pskc:PlainValue>playreadyContentKey</pskc:PlainValue>
                </pskc:Secret>
            </cpix:Data>
        </cpix:ContentKey>
    </cpix:ContentKeyList>
    <cpix:DRMSystemList>
        <cpix:DRMSystem kid="someKid" systemId="9a04f079-9840-4286-ab92-e65be0885f95">
            <speke:ProtectionHeader>playreadyProtectionHeader</speke:ProtectionHeader>
            <cpix:PSSH>playreadyPSSHBox</cpix:PSSH>
        </cpix:DRMSystem>
        <cpix:DRMSystem kid="someKid" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
            <PSSH>widevinePSSHBox</PSSH>
        </cpix:DRMSystem>
    </cpix:DRMSystemList>
</cpix:CPIX>



Legacy JSON Key Provider API

❗️

WARNING

Use the CPIX API to retrieve encryption keys. This Legacy JSON Key Provider API is maintained for backwards compatibility

The Legacy JSON Key Provider API provides all the information required to encrypt various types of content. Since different systems require different values, the API returns encryption keys in base16 and base64.

The following sections describe the requests and responses in order to retrieve the keys. The most common scenario is to request CENC and FairPlay encryption keys.


Retrieve encryption keys

https://keyprovider.vudrm.tech/{drm_type}/{client_name}/{content_id}
Retrieves encryption keys


Request

curl -X GET https://https://keyprovider.vudrm.tech/{drm_type}/{client_name}/{content_id} \
     -H 'API-KEY: {api_key}'

Path Parameters

Parameter Description
client_name Account name

Please contact JW Player Support if you do not have an account name.
content_id Unique identifier for the content

This value will always generate the same encryption keys.

This must only contain alphanumeric characters, hyphens (-), or underscores (_)
drm_type Type of encryption keys being requested

Possible values:
Β Β Β β€’ cenc
Β Β Β β€’ fairplay
Β Β Β β€’ playready
Β Β Β β€’ widevine

πŸ“˜

In order to provide the keys securely, an API key is required in the header of the request. Please contact JW Player Support if you do not have an API key.


Response

In order to provide the keys securely, the DRM encryption keys are encrypted in the response.

{  "key":"r8tXpf8wSSHKVnW1fz+MgZY3BTnTO+/IGFglt9oUwtKWj8eyguSLd0bzOhcn4DMF4JWOAbhbKopJE/cZWPqIfl3RCIwl46UP57/m7870+z3NWxh/JSvrfWBq4SGmkykfDLKjyLBqb5F6dDlUB+flcfZMcQh6FGk5GNGEniXliB/kyCrVDiKdwAw3hft8rT4/itFQDMRKkhJf1Fh67AZ1LyzOI3CCY/oO4w/XF/XMAJ1z92tAKULI+cPMFaXT3I77N3iaQoYN78mJkKgAr71Tlf91+ASB8jqOCHD6nNgm6nGxZlsTVK5wxdhT4zbMJq4xb7daSy7xMWdH/1eXuIh0ZhWicKJqbWHKIeifZWFras/0QzqN27rupHF3UYnYQ40V3ESE2PUIe8Cs8471QRHlruYlwtgBBmGme2ERZWFjrRFEeUt8SobQkCIZrzDEKaQ2bJMyOy1yMt8oklpFaW9pBg3yHZEK1WZn5u8ynV+ZWLI6soCNpMgkPYe2UtnFOhFRZfT8WG09FGJiouzyL3fCZAguxP8u9jkzQTv15UhwO/StdpTKCn1yxr3KoyxGAk3L|166c43d4023880a99691fd9679e6ad785305f205"
} 

Response Parameter

Parameter Description
key Encrypted DRM encryption keys

The value has two components separately by a pipe (|):
Β Β Β β€’ Encrypted blob containing the DRM encryption keys
Β Β Β β€’ Hash used in a checksum



Decrypt the response

Use the following code to decrypt the response from the Legacy JSON Key Provider API.


Requirements

  • client_name
  • key (from the API response)
  • shared_secret
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Vudrm.EncryptionExamples
{
    class Program
    {
        private const string Client = "CLIENT_NAME";
        private const string SharedSecret = "SHARED_SECRET";
        private const string KeyProviderResponse = "KEY_PROVIDER_RESPONSE";
        
        static void Main(string[] args)
        {
            Console.WriteLine("Decrypting keyprovider API response...");
            var splitKeyProviderResponse = KeyProviderResponse.Split('|');
            var computedHash = ComputeHash(SharedSecret, Client, splitKeyProviderResponse[0]);
            if (computedHash == splitKeyProviderResponse[1])
            {
                Console.WriteLine("key providers response hash passed validation");
                var decryptedKeyProviderResponse = Decrypt(splitKeyProviderResponse[0], SharedSecret);
                Console.WriteLine("Decrypted key provider response: " + decryptedKeyProviderResponse);
            }
            else
            {
                Console.WriteLine("Key provider response hash did not validate");
            }
            Console.ReadLine();
        }

        private string Decrypt(string policy, string sharedSecret)
        {
            try
            {
                var encrypted = Convert.FromBase64String(policy);
                var key = Encoding.ASCII.GetBytes(sharedSecret.Substring(0, 16));
                var rj = new RijndaelManaged
                {
                    Mode = CipherMode.ECB,
                    BlockSize = 128,
                    Key = key
                };
                var decryptor = rj.CreateDecryptor(key, null);
                var ms = new MemoryStream(encrypted);
                var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
                var plain = new byte[encrypted.Length];
                var decryptcount = cs.Read(plain, 0, plain.Length);
                ms.Close();
                cs.Close();
                return (Encoding.UTF8.GetString(plain, 0, decryptcount));
            }
            catch
            {
                return policy;
            }
        }

        private string ComputeHash(string sharedSecret, string client, string encryptedMessage)
        {
            var preComputed = sharedSecret + client + encryptedMessage;
            var algorithm = new SHA1Managed();
            var bytesOf = Encoding.UTF8.GetBytes(preComputed);
            var hashOf = algorithm.ComputeHash(bytesOf);
            var result = new StringBuilder();
            foreach (var b in hashOf)
            {
                result.Append(b.ToString("x2").ToLower());
            }
            return result.ToString();
        }
    }
}
package main

import (
	"crypto/aes"
	"crypto/sha1"
	"encoding/base64"
	"errors"
	"fmt"
	"strings"
)

var (
	Client = "CLIENT"
	SharedSecret = "SHARED_SECRET"
	KeyProviderResponse = "KEY_PROVIDER_RESPONSE"
	PKCS5 = &pkcs5{}
)

type pkcs5 struct{}

func main() {
	s := strings.Split(KeyProviderResponse, "|")
	encryptedMessage, hash := s[0], s[1]
	generatedHash := generateKeyProviderHash(SharedSecret, Client, encryptedMessage)
	if generatedHash == hash {
		decryptedKeys := decrypt(encryptedMessage, SharedSecret)
		fmt.Printf(decryptedKeys)
	} else {
		fmt.Printf("hash failed validation")
	}
}

func generateKeyProviderHash(sharedSecret string, client string, encryptedMessage string) string {
	v := fmt.Sprintf("%s%s%s", sharedSecret, client, encryptedMessage)
	hasher := sha1.New()
	hasher.Write([]byte(v))
	return fmt.Sprintf("%x", hasher.Sum(nil))
}

func decrypt(encryptedData string, sharedSecret string) string {
	source, _ := base64.StdEncoding.DecodeString(encryptedData)
	key := []byte(sharedSecret)[0:16]

	cipher, _ := aes.NewCipher([]byte(key))
	buffer := make([]byte, len(source))
	size := 16

	for bs, be := 0, size; bs < len(source); bs, be = bs+size, be+size {
		cipher.Decrypt(buffer[bs:be], source[bs:be])
	}

	plainBytes, _ := PKCS5.unPadding(buffer, 16)
	return string(plainBytes)
}

func (p *pkcs5) unPadding(src []byte, blockSize int) ([]byte, error) {
	srcLen := len(src)
	paddingLen := int(src[srcLen-1])
	if paddingLen >= srcLen || paddingLen > blockSize {
		return nil, errors.New("padding size error")
	}
	return src[:srcLen-paddingLen], nil
}
import base64
import binascii
import json
import hashlib

from Crypto.Cipher import AES

client = "CLIENT"
shared_secret = "SHARED_SECRET"
key_provider_response = "KEY_PROVIDER_RESPONSE"

print("Decrypting Key Provider Response...")
split_key_provider_response = key_provider_response.split("|")
pre_computed = (shared_secret + client + split_key_provider_response[0]).encode("utf-8")
computed_hash = hashlib.sha1(pre_computed).hexdigest()
if computed_hash == split_key_provider_response[1]:
    key = shared_secret[0:16]
    decoded_text = base64.b64decode(split_key_provider_response[0])
    aes = AES.new(key.encode("utf8"), AES.MODE_ECB)
    padded_text = aes.decrypt(decoded_text)
    unpadded_text = padded_text[:-padded_text[-1]]
    decrypted_keys = json.loads(unpadded_text)
    print("Decrypted keys: " + json.dumps(decrypted_keys))
else:
    print("Hash validation failed for key provider response!")
require 'base64'
require 'crypt/rijndael'
require 'digest'
require 'openssl'

client = "CLIENT_NAME"
shared_secret = "SHARED_SECRET"

encrypted_keys = "KEY_PROVIDER_RESPONSE"

message, message_hash = encrypted_keys.split('|')

pre_computed = client + message
computed_hash = Digest::SHA1.new.hexdigest(shared_secret + pre_computed)

if computed_hash == message_hash
  decoded_message = Base64.strict_decode64(message)
  decipher = OpenSSL::Cipher::Cipher.new('AES-128-ECB').decrypt
  decipher.key = shared_secret[0..15]
  unencrypted_keys = decipher.update(decoded_message) + decipher.final
else
  raise "Key provider response hash did not validate"
end



Use the encryption keys

Each set of encryption keys returned by the API has a different use case. For use with Unified Streaming products, CENC and FairPlay encryption keys are recommended. See the Unified Streaming Integration section below for more details on how to use mp4split with the Legacy JSON Key Provider API.

πŸ“˜

The following encryption key examples use the Legacy JSON Key Provider API. However, the JSON keys retrieved from the CPIX Key Provider API can be used in the same manner.




CENC

The Common Encryption Scheme (CENC) standardizes encryption keys between different DRM systems. This allows a single set of encryption keys to be used to encrypt a single file using different DRM systems. Studio DRM supports Widevine and PlayReady when generating CENC encryption keys.


Request

curl -X GET https://keyprovider.vudrm.tech/cenc/{client}/{content_id} 
     -H 'API_KEY: <API_KEY>'

Response

The keys returned in this response can be used for PlayReady and Widevine scenarios. They allow a single piece of content to be used across multiple devices and browsers. The following response is a decrypted response example.

{
    "key_id_big": "qMTumUz5drgbusWY+fi5LA==",
    "key_id_hex": "A8C4EE994CF976B81BBAC598F9F8B92C",
    "content_key": "ETweRxyDIuDqAadsWdx0HQ==",
    "content_key_hex": "113C1E471C8322E0EA01A76C59DC741D",
    "playready_key_iv": "dd80b66b2fe44be4",
    "playready_laurl": "https://playready-license.vudrm.tech/rightsmanager.asmx",
    "playready_checksum": "j+7cluk2J58=",
    "widevine_drm_specific_data": "Ig1zb21lY29udGVudGlkSOPclZsG",
    "widevine_laurl": "https://widevine-license.vudrm.tech/proxy"
}

Response Parameters

Parameter Description
content_key 128-bit encryption key in base64 in Big Endian
content_key_hex 128-bit encryption key in base16 in Little Endian

This value should be used with `mp4split`
key_id_big Unique ID for the encryption in base64 in Big Endian
key_id_hex Unique ID for the encryption in base16 in Little Endian

This value should be used with `mp4split`.
playready_checksum Security value required by some older PlayReady solutions and Wowza
playready_key_iv Additional random value to strengthen the PlayReady encryption
playready_laurl PlayReady license server URL
widevine_drm_specific_data Widevine PSSH data
widevine_laurl Widevine license server URL



FairPlay

Apple's DRM system, FairPlay, is commonly used in conjunction with CENC encryption to provide support to the widest amount of devices possible.


Request

curl -X GET https://keyprovider.vudrm.tech/fairplay/{client}/{content_id} 
     -H 'API_KEY: {api_key}'

Response

The following response is a decrypted response example.

{
    "key_hex": "457A8E3300DE6D549A95037F1C7ADEB1",
    "iv_hex": "EB86EAFBD487391383E8FFF957561B0C",
    "laurl": "skd://fairplay-license.vudrm.tech/license/somecontentid"
}

Response Parameters

Parameter Description
iv_hex Encryption key
key_hex Unique ID for the encryption
laurl Fairplay license server URL

At the point of the request to the license server the `skd://` protocol should be replaced with `https://` protocol.



PlayReady

PlayReady is Microsoft's DRM system. Only use these keys to target PlayReady-enabled devices directly. The use of CENC keys is preferred.


Request

curl -X GET https://keyprovider.vudrm.tech/playready/{client}/{content_id} 
     -H 'API_KEY: {api_key}'

Response

The following response is a decrypted response example.

{
    "key_id":"kX9efHkfIS++X+m8kZPDOw==",
    "key_id_guid":"7c5e7f91-1f79-2f21-be5f-e9bc9193c33b",
    "key_id_uuid":"917f5e7c791f-2f21-be5fe9bc9193c33b",
    "key_id_hex":"917F5E7C791F212FBE5FE9BC9193C33B",
    "content_key":"eI5JjujIo1Ek7lqO+3gg0A==",
    "content_key_hex":"788E498EE8C8A35124EE5A8EFB7820D0",
    "laurl":"http://vualto.playready-license.vudrm.tech/rightsmanager.asmx",
    "service_id":"gwICI8yfIUGf4R/5qOWuqg==",
    "service_id_guid":"23020283-9fcc-4121-9fe11ff9a8e5aeaa",
    "key_iv":"07261ee6ee074f1d",
    "checksum":"wf0goCGB2O4="
}

Response Parameters

Parameter Description
checksum Extra security value required by some older PlayReady solutions
content_key 128-bit encryption key in base64
content_key_hex 128-bit encryption key in base16

This value should be used with `mp4split`.
key_id Unique ID for the encryption in base64 in Big Endian
key_id_guid Unique ID for the encryption, GUID in Big Endian
key_id_hex Unique ID for the encryption in base16 in Little Endian

This value should be used with `mp4split`.
key_id_uuid Unique ID for the encryption, UUID in Little Endian
key_iv Additional random value to strengthen the PlayReady encryption
laurl PlayReady license server URL
service_id Unique Studio DRM service ID for JW Player in base64
service_id_guid Unique Studio DRM service ID for JW Player as a GUID



Widevine

Widevine is Google's DRM system. Use these keys to target Widevine-enabled devices directly. The use of CENC keys is preferred.


Request

curl -X GET https://keyprovider.vudrm.tech/widevine/{client}/{content_id} 
     -H 'API_KEY: {api_key}'

Response

The following response is a decrypted response example.

{
    "key_id":"NxB8uJFHVSuaO5BjiMzuEQ==",
    "key_id_hex":"37107CB89147552B9A3B906388CCEE11",
    "content_key":"Unyx1s3fMFUedA688fCNxw==",
    "content_key_hex":"527CB1D6CDDF30551E740EBCF1F08DC7",
    "laurl":"https://widevine-license.vudrm.tech/proxy",
    "drm_specific_data":"CAESEDcQfLiRR1UrmjuQY4jM7hEaBnZ1YWx0byIFdGVzdDEqAkhEMgA="
} 

Response Parameters

Parameter Description
content_key 128-bit encryption key in base64
content_key_hex 128-bit encryption key in base16

This value should be used with `mp4split`.
drm_specific_data Widevine PSSH box
key_id Unique ID for the encryption in base64 in Little Endian
key_id_hex Unique ID for the encryption in base16 in Little Endian

This value should be used with `mp4split`.
laurl Widevine license server URL



Unified Streaming Integration

The encryption keys provided by the Legacy JSON Key Provider APIs are compatible with Unified Streaming's mp4split packaging product.


The recommended approach is to call the CPIX Key Provider API to retrieve CENC and FairPlay keys. Once the encryption keys have been retrieved they can be used with mp4split to generate an .ism file.

mp4split --license-key=$LICENSE_KEY -o $ISM \
 --iss.key=${key_id_hex}:${content_key_hex} \
 --iss.key_iv=${playready_key_iv} \
 --iss.license_server_url=${playready_laurl} \
 --widevine.key=${key_id_hex}:${content_key_hex} \
 --widevine.license_server_url=${widevine_laurl} \
 --widevine.drm_specific_data=${widevine_drm_specific_data} \
 --hls.client_manifest_version=4 \
 --hls.key=:${key_hex} \
 --hls.key_iv=${iv_hex} \
 --hls.license_server_url=${laurl} \
 --hls.playout=sample_aes_streamingkeydelivery

The HLS values come from the FairPlay encryption keys. All other values are from the CENC keys.