Common Encryption - aureliendavid/gpac GitHub Wiki

HOME » MP4Box » Encryption » Common Encryption

MP4Box is able to encrypt and decrypt ISOBMFF files according to CENC specification (ISO/IEC 23001-7:2016), including latest pattern encryption tools introduced in the standard.

In order to encrypt or decrypt an MP4 file, MP4Box will need a side file containing all informations about crypto/DRM system and the informations needed to encrypt a given track, hereafter refered as drm_file. Sample files are available at gpac/tests/media/encryption/

The file is an XML with the following syntax:

XML Syntax

<GPACDRM type="...">
 <DRMInfo >
    ...
 </DRMInfo>
 <CrypTrack  trackID="..." [see possible attributes below] >
  <key KID="..." value="..."/>
  <key KID="..." value="..."/>
 </CrypTrack>
</GPACDRM>

Semantics

  • type : is the default protection scheme type used for all tracks in the source media file. The possible values are (full name or 4 char code):

    • ISMA or iAEC: ISMA E&A (ISMACryp) Scheme
    • Adobe or adkm: Adobe Scheme
    • CENC AES-CTR or cenc: CENC Protection Scheme using AES 128-bit keys in Counter Mode (AES-128 CTR),
    • CENC AES-CBC or cbc1: CENC Protection Scheme using AES 128-bit keys in Cipher-block chaining mode (AES-128 CBC),
    • CENC AES-CTR Pattern or cens: CENC Protection Scheme using AES 128-bit keys in Counter Mode (AES-128 CTR) using pattern of unencrypted/encrypted bytes,
    • CENC AES-CBC Pattern or cbcs: CENC Protection Scheme using AES 128-bit keys in Cipher-block chaining mode (AES-128 CBC) using pattern of unencrypted/encrypted bytes,
  • DRMInfo : contains information needed by a Content Protection System to play back the content such as SystemID, the URL of license server(s) or rights issuer(s) used, embedded licenses/rights, embedded keys(s), and/or other protection system specific metadata. Note that it is possible to specify  more than one DRM system, each one correspond to one tag DRMInfo. The following example shows a simple GPAC DRM system info:

    Simple GPAC DRM system info

    <!-- example for GPAC 'clear' DRM System - keys are listed after the content and UL follows -->
    <DRMInfo type="pssh" version="1" cypherOffset="9" cypherKey="0x6770616363656E6364726D746F6F6C31" cypherIV="0x00000000000000000000000000000001">
        <BS ID128="6770616363656E6364726D746F6F6C31"/>
        <BS value="2" bits="32"/>
        <BS ID128="0x279926496a7f5d25da69f2b3b2799a7f"/>
        <BS ID128="0x676cb88f302d10227992649885984045"/>
        <BS bits="8" string="CID=Toto"/>
        <BS ID128="0xccc0f2b3b279926496a7f5d25da692f6"/>
        <BS ID128="0xccc0f2b3b279926496a7f5d25da692d6"/>
    </DRMInfo>
  • trackID : specifies the track ID to encrypt. If not set, this crypt configuration applies to all tracks for which no CryptTrack with a trackID is specified.

  • type: is the protection scheme type used for this track. If not set, use the type specified at GPACDRM level. Syntax is the same as type at GPACDRM level.

  • forceType: if set, type is used during decryption instead of scheme type information indicated in encrypted track.

  • IsEncrypted : is the flag which indicates the encryption state of the samples in this track. Default is 1.

  • IV_size : is the size in bytes of the Initialization Vector. It should be 0 (if track is not encrypted i.e the IsEncrypted flag is 0x0), 8 or 16. When not set, guessed from the size of the first_IV attribute.

  • first_IV : is the first Initialization Vector used for this track. If the scheme type uses constant IV and constant_IV attribute is not present, this will be used as constant IV.

  • selectiveType : specifies how selective encryption is to be used. The possible values are:

    • None : no selective encryption, all samples encrypted (this is the default behavior).
    • Clear: samples are not encrypted but track is signaled as using encryption.
    • RAP : only Random Access Samples (key frames) will be encrypted. If all media samples are RAPs, this defaults to None.
    • Non-RAP : only non-Random Access Samples (non-key frames) will be encrypted. If all media samples are RAPs, this defaults to None.
    • Rand : random selection of samples to encrypt is performed.
    • X : encrypts the first sample every X samples. X must be an integer greater than 2.
    • RandX : encrypts one random samples out of X samples. X must be an integer greater than 2.
  • saiSavedBox : type of the box where we save the CENC sample auxiliary information. The possible values are:

    • uuid_psec : box type 'uuid', extend-type = 0xA2394F52-5A9B-4f14-A244-6C427C648DF4, according to The Protected Interoperable File Format (PIFF) specification of Microsoft.
    • senc : box type 'senc', according to HbbTV 1.5 and CFF 1.0.5 specifications. This is the default value.
  • keyRoll : key selection policy and key rolling configuration. The possible values are:

    • IDX=N : use only key whose index is N for encrypting this track. By default, the first key is used. (Note: we use the zero-based index)
    • roll=N : Common Encryption allows groups of samples within the track to use different keys. The encryption parameters (i.e KID, initialization vector size and encryption flag) are contained in a 'SampleGroupDescriptionBox' and will override the default parameters for this track. If this option is set, each N encrypted samples will share the same key supported by the DRM system.
  • key : the AES-128 bit keys to use. The key ID and key value must be specified as an 32 bytes hex string. This is a mandatory field, not specifing it or using an improper length will result in an error. Note that we support the multiple key encryption. Key selection policy and key rolling are determinated by 'keyRoll' attribute.

  • skip_byte_block : number of 16-bytes blocks in the clear at the begining of the encryption pattern. When not set and the scheme type uses pattern (cens, cbcs), a value of 9 is assumed for NAL-based tracks and 0 for other tracks.

  • crypt_byte_block : number of 16-bytes blocks encrypted at the begining of the encryption pattern. When not set and the scheme type uses pattern (cens, cbcs), a value of 1 is assumed.

  • constant_IV_size : size of constant IV used in pattern encryption mode. When not set, guessed from the size of the constant_IV attribute.

  • constant_IV : constant IV used for all samples in cbcs pattern encryption mode. If IV_size is set, constant IV is ignored and each sample has a dedicated IV.  If the scheme type does not use constant IV and first_IV attribute is not present, this will be used as the first IV.

  • encryptSliceHeader: enables old behaviour for cenc scheme for AVC in avc1 mode, for which slice headers (and other nal such as SEI) can be encrypted.

  • clear_bytes: number of bytes to leave in the clear for non NAL-based tracks. Only used in cbcs mode.

  • blockAlign: for 'cenc' scheme, enforces block alignment (multiple of 16 bytes) for encrypted part of subsamples to avoid partial cipher blocks at the end of subsamples. The possible values are:

    • always: always perform block alignment, even if resulting sample is not encrypted
    • disable: never perform block alignment
    • default: performs block alignment unless the resulting sample would nit be encrypted. This is the default behaviour.

Encrypting/Decrypting a MP4 file with GPAC

The command line is as follows:

MP4Box -crypt drm_file.xml movie.mp4 -out movie_encrypted.mp4
MP4Box -decrypt drm_file.xml movie_encrypted.mp4 -out movie_decrypted.mp4

The following example shows an example file drm_file_gpac_clear.xml for encrypting all samples in a track, using only one key, and with GPAC 'clear' DRM System:

drm_file_gpac_clear.xml

<?xml version="1.0" encoding="UTF-8"?>
<GPACDRM type="CENC AES-CTR">
<!-- example for GPAC 'clear' DRM System - keys are listed after the content and UL follows -->
    <DRMInfo type="pssh" version="1" cypherOffset="9" cypherKey="0x6770616363656E6364726D746F6F6C31" cypherIV="0x00000000000000000000000000000001">
        <BS ID128="6770616363656E6364726D746F6F6C31"/>
        <BS value="2" bits="32"/>
        <BS ID128="0x279926496a7f5d25da69f2b3b2799a7f"/>
        <BS ID128="0x676cb88f302d10227992649885984045"/>
        <BS bits="8" string="CID=Toto"/>
        <BS ID128="0xccc0f2b3b279926496a7f5d25da692f6"/>
        <BS ID128="0xccc0f2b3b279926496a7f5d25da692d6"/>
    </DRMInfo>
    <CrypTrack trackID="1" IsEncrypted="1" IV_size="16" first_IV="0x0a610676cb88f302d10ac8bc66e039ed" saiSavedBox="senc">
        <key KID="0x279926496a7f5d25da69f2b3b2799a7f" value="0xccc0f2b3b279926496a7f5d25da692f6"/>
        <key KID="0x676cb88f302d10227992649885984045" value="0xccc0f2b3b279926496a7f5d25da692d6"/>
    </CrypTrack>
</GPACDRM>

In the above XML, the BS element from NHML syntax is used to describe what needs to be written in the PSSH box. In this example, the PSSH block contains:

  • 128 bit system ID
  • key IDs count (2) on 32 bits
  • two key IDs on 128 bits each
  • 8 byte string prefixed with a length size on 8 bits
  • two keys on 128 bits each

For more information on what is supported by the BS element, check the NHML documentation.

Another example drm_file_2_drms.xml shows how to use 2 DRM Systems:

drm_file_2_drms.xml

<?xml version="1.0" encoding="UTF-8"?>
<GPACDRM type="CENC AES-CTR">
<!-- PlayReady - data contains the cyphered key & co -->
    <DRMInfo type="pssh" version="0">
        <BS ID128="9A04F07998404286AB92E65BE0885F95"/> <!-- SystemID -->
        <BS data="application/data;base64:ACE125"/> <!-- binary blob, could also use dataFile="cenc_blob.bin" -->
    </DRMInfo>
    <!-- GPAC 'clear' DRM System - keys are listed after the content and UL follows -->
    <DRMInfo type="pssh" version="1" cypherOffset="9" cypherKey="0x6770616363656E6364726D746F6F6C31" cypherIV="0x00000000000000000000000000000001">
        <BS ID128="6770616363656E6364726D746F6F6C31"/>
        <BS value="2" bits="32"/>
        <BS ID128="0x279926496a7f5d25da69f2b3b2799a7f"/>
        <BS ID128="0x676cb88f302d10227992649885984045"/>
        <BS bits="8" string="CID=Toto"/>
        <BS ID128="0xccc0f2b3b279926496a7f5d25da692f6"/>
        <BS ID128="0xccc0f2b3b279926496a7f5d25da692d6"/>
    </DRMInfo>
    <CrypTrack trackID="1" IsEncrypted="1" IV_size="16" first_IV="0x0a610676cb88f302d10ac8bc66e039ed" saiSavedBox="senc">
        <key KID="0x279926496a7f5d25da69f2b3b2799a7f" value="0xccc0f2b3b279926496a7f5d25da692f6"/>
        <key KID="0x676cb88f302d10227992649885984045" value="0xccc0f2b3b279926496a7f5d25da692d6"/>
    </CrypTrack>
</GPACDRM>

In the above XML, there are 2 PSSH blocks. For a non-GPAC DRM block, the opaque DRM specific data can be generated using the BS syntax or read from a data attribute or from a file indicated in dataFile attribute. Another example drm_file_rap.xml shows an advanced case: we will encrypt only the RAP and we use also key rolling policy.

drm_file_rap.xml

<?xml version="1.0" encoding="UTF-8"?>
<GPACDRM type="CENC AES-CTR">
    <DRMInfo type="pssh" version="1" cypherOffset="9" cypherKey="0x6770616363656E6364726D746F6F6C31" cypherIV="0x00000000000000000000000000000001">
        <BS ID128="6770616363656E6364726D746F6F6C31"/>
        <BS value="4" bits="32"/>
        <BS ID128="0x279926496a7f5d25da69f2b3b2799a7f"/>
        <BS ID128="0x597669572e55547e656b56586e2f6f68"/>
        <BS ID128="0x205b2b293a342f3d3268293e6f6f4e29"/>
        <BS ID128="0x32783e367c2e4d4d6b46467b3e6b5478"/>
        <BS bits="8" string="CID=Toto"/>>
        <BS ID128="0x5544694d47473326622665665a396b36"/>
        <BS ID128="0x7959493a764556786527517849756635"/>
        <BS ID128="0x3a4f3674376d6c48675a273464447b40"/>
        <BS ID128="0x3e213f6d45584f51713d534f4b417855"/>
    </DRMInfo>
    <CrypTrack trackID="1" IsEncrypted="1" IV_size="16" first_IV="0x0a610676cb88f302d10ac8bc66e039ed" selectiveType="RAP" saiSavedBox="senc" keyRoll="roll=5">
        <key KID="0x279926496a7f5d25da69f2b3b2799a7f" value="0x5544694d47473326622665665a396b36"/>
        <key KID="0x597669572e55547e656b56586e2f6f68" value="0x7959493a764556786527517849756635"/>
        <key KID="0x205b2b293a342f3d3268293e6f6f4e29" value="0x3a4f3674376d6c48675a273464447b40"/>
        <key KID="0x32783e367c2e4d4d6b46467b3e6b5478" value="0x3e213f6d45584f51713d534f4b417855"/>
    </CrypTrack>
</GPACDRM>

Adobe's Protection Scheme Support in MP4Box

Adobe's Protection Scheme is now supported in GPAC (dump/encrypt/decrypt) using the base syntax. The below example shows a drm_file using for Adobe cryto:

drm_file.xml

<?xml version="1.0" encoding="UTF-8"?>
<GPACDRM type="ADOBE">
    <CrypTrack trackID="1" IsEncrypted="1" first_IV="0x0a610676cb88f302d10ac8bc66e039ed" selectiveType="RAP" metadata="url=toto" metadata_len="8">
        <key value="0x5544694d47473326622665665a396b36"/>
    </CrypTrack>
</GPACDRM>

In this example, metadata is a string used by the DRM client to retrieve decryption key

Playing an encrypted file with GPAC Player

GPAC Player can play protected files which use the GPAC SystemID, in which keys are carried in an unencrypted PSSH box  :) If you want to play with the sample decryption module to add your own CENC system, have a look at gpac/modules/ismacryp/isma_ea.c

⚠️ **GitHub.com Fallback** ⚠️