Clear key encryption using MP4BOX - Google Groups

133 downloads 454 Views 598KB Size Report
What tools are needed and where are they ? MP4Box to encrypt or decrypt ... drm_file. It is an XML file whose syntax loo
Clear key encryption using MP4BOX Overview This pages explains how to manage clearkey encryption using MP4BOX.

What tools are needed and where are they ? MP4Box to encrypt or decrypt video according to CENC specification a.k.a ISO/IEC 23001-7:2012. Issue to projet GPAC from Telecom ParisTech. CryptfileBuilder to assist the generation of MP4Box cryptfiles.

Version to use is at least version : 0.5.2

Linux version

Window version

Linux version is available here on red hat 6 .

version is available here :

Connect to a machine that contents this version.

http://gpac.wp.mines-telecom.fr/downloads/gpac-nightly-builds/#Windows%2064%2

Binary is available here : /a/opt.softs/workshop/4.0/bin/MP4Box Library is available here: /a/opt.softs/workshop/4.0/lib/libgpac.so

Add following env variable to be able to use it: export PATH=/a/opt.softs/workshop/4.0/bin:$PATH export LD_LIBRARY_PATH=/a/opt.softs/workshop/4.0/lib:$LD_LIBRARY_PATH

In order to encrypt or decrypt an MP4 file, MP4Box will need a specific file containing all information about crypto system (i.e. DRM system) and the informations needed to encrypt a given track, hereafter refered as drm_file. It is an XML file whose syntax looks like this:

XML Syntax

1 2 3 4 5 6 7 8 9

...

Semantics

type : is the protection scheme type used for this MP4 file. The possible values are: ISMA : media > trackID : specifies the track ID to encrypt. This is a mandatory field, not specifying it will result in an error. In our case, track 2 is encrypted which corresponds to video track (first track is audio). IsEncrypted : is the flag which indicates the encryption state of the samples in this track IV_size : is the size in bytes of the InitializationVector field. It should be 0 (if track is not encrypted i.e the IsEncrypted flag is 0x0), 8 or 16 first_IV : is the first InitializationVector used for this track. 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). 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. 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 encryptedsamples 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.

There are 2 syntax for the header according to the version : 4.1.0.0 or 4.0.0.0, defined in : http://www.microsoft.com/playready/documents/ playready_wrm_v4100_utf16.xml has following format :

1 2 3 4 5 6

< ALGID="AESCTR" CHECKSUM="fm+3IvdgFnU" /> http://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&UseSimpleNonPersistentLicense=1 16 AESCTR http://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&UseSimpleNonPersistentLicense=1 AAAAIAAgACAgACAAAAAAAg== fm+3IvdgFnU=

Content Key Generation We have following correspondence between MS binary and Base64 format. =============================================== Content key ID = 0x20000000200020002000200000000002 0x00000020002000202000200000000002 (MS binary) IAAAACAAIAAgACAAAAAAAg== (Base64) AAAAIAAgACAgACAAAAAAAg== (Base64, MS binary) Content key = 0x881494BC53A489479F267A521C9FE343 iBSUvFOkiUefJnpSHJ/jQw== (Base64) Checksum = 0x7E6FB722F7601675 fm+3IvdgFnU= (Base64) IV = 0x6403E7BBEBA1B785 ZAPnu+uht4U= (Base64) ===============================================

What is the key wrapping ?

A "wrapped key" is a cryptographic key which has been encrypted or otherwise protected using another key, usually known as a Key Encryption

Key (KEK). An example of an algorithm used to wrap keys is AES Key Wrap . AES Key Wrap uses an AES Key to perform the wrapping. It does not specify the format of the key to be wrapped. Another example is RSA-KEM . 1. The WebCrypto API should support a Key Wrapping operation. The Key Wrapping operation first formats the information associated with a Key object into a serializable form (as in the existing export operation) and then applies a Key Wrap Algorithm, using a Key Encryption Key (also represented as a Key object) to produce a wrapped key (in the form of an octet string). 2. The WebCrypto API should support a Key Unwrapping operation. The Key Unwrapping operation takes a wrapped key, applies the inverse of a Key Wrap Algorithm, using a Key Encryption Key (also represented as a Key object) and then de-serializes the result (as in the existing import operation) to produce a new Key object 3. Key wrapping and unwrapping should support the same serialized key formats as the existing import and export operations 4. For the JSON Web Key format, additional attributes may be included in the format as well as the raw key data. Mappings should be specified between attributes in the JWK structure to and from the type, algorithm, extractable and keyUsages attributes of the Key object. 5. When unwrapping raw key data, it shall be possible for the user to specify the type, algorithm, extractable and keyUsages attributes of the Key object. 6. When unwrapping JWK key data, the values of the type, algorithm, extractable and keyUsages attributes of the Key object shall be taken from the JWK structure. It shall be possible to specify defaults for the case where these attributes are not present in the JWK structure. 7. If necessary, the WebCrypto specification shall define additional JKW structure members as necessary to achieve the above. 8. Key Wrapping and Unwrapping shall be specified for at least the following kinds of key: AES keys, HMAC keys, .. See : http://www.w3.org/2012/webcrypto/wiki/KeyWrap_Proposal

How to get fields to fill xml file ?

There are various approaches in generating content key IDs and content keys. See: http://azure.microsoft.com/blog/2014/11/17/an-end-to-end-prototype-of-playready-protection-with-acs-authentication-and-acs-token-authoriz ation/ (section Content key generation)

There are some java files that allows to transform an key_id in UUID format passed as input parameter and produces in output content key, check sum and IV part , needed to fill fields in xml file.

Parameter in the java file PlayReadyKeygen.java is : 20000000-2000-2000-2000-200000000002

How to check video is crypted ? To check information on the video tape :

MP4Box.exe -info encoded_big_buck_bunny.mp4

* Movie Info * Timescale 600 - Duration 00:01:00.095 4 track(s) Fragmented File: no File suitable for progressive download (moov before mdat) File Brand mp42 - version 1 Created: GMT Tue Feb 9 01:55:39 2010 Modified: GMT Tue Feb 9 01:55:40 2010 File has no MPEG4 IOD/OD 1 UDTA types: hnti (1) Track # 1 Info - TrackID 1 - TimeScale 22050 - Media Duration 00:01:00.139 Track has 1 edit lists: track duration is 00:01:00.095 Media Info: Language "eng (eng)" - Type "soun:mp4a" - 1295 samples MPEG-4 Config: Audio Stream - ObjectTypeIndication 0x40 MPEG-4 Audio AAC LC - 2 Channel(s) - SampleRate 22050 Self-synchronized RFC6381 Codec Parameters: mp4a.40.2 All samples are sync Track # 2 Info - TrackID 2 - TimeScale 600 - Media Duration 00:01:00.095 Track has 1 edit lists: track duration is 00:01:00.095 Media Info: Language "eng (eng)" - Type "vide:encv" - 1440 samples Visual Track layout: x=0 y=0 width=640 height=360 MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x21 AVC/H264 Video - Visual Size 640 x 360 AVC Info: 1 SPS - 1 PPS - Profile Baseline @ Level 3 NAL Unit length bits: 32 SPS#1 hash: 07E0BF5052E1BE80E9FF5928FA7432D83F77A5B2 PPS#1 hash: 4460C4AF34AC814BB6E89EA6C5B3418980100174 Synchronized on stream 1 *Encrypted stream - CENC scheme cenc (version 65536) Initialization Vector size: 64 bits RFC6381 Codec Parameters: avc1.42e01e Average GOP length: 62 samples Track # 3 Info - TrackID 3 - TimeScale 90000 - Media Duration 00:01:00.095 Track has 1 edit lists: track duration is 00:01:00.095 Track is disabled Media Info: Language "eng (eng)" - Type "hint:rtp " - 1440 samples 3 UDTA types: name (1) hnti (1) hinf (1) Streaming Hint Track for track ID 2 Payload ID 96: type H264/90000 RFC6381 Codec Parameters: rtp Average GOP length: 62 samples Track # 4 Info - TrackID 4 - TimeScale 22050 - Media Duration 00:01:00.139 Track has 1 edit lists: track duration is 00:01:00.095 Track is disabled Media Info: Language "eng (eng)" - Type "hint:rtp " - 648 samples 3 UDTA types: name (1) hnti (1) hinf (1) Streaming Hint Track for track ID 1 Payload ID 97: type mpeg4-generic/22050/2 RFC6381 Codec Parameters: rtp All samples are sync

You can check the video is crypted using VLC, as the video shows black content.

To decrypt video MP4Box.exe -v -decrypt drm_file_play_ready.xml big_buck_bunny_crypted_play_ready.mp4 -out big_buck_bunny_decrypted_play_ready.mp4 The it can be played using VLC

A test site provided by microsoft allows to test EME/MSE play ready protection : http://testdrive-eme.azurewebsites.net/

Problems 1°) There are some EME/MSE javascript tests to played the encrypted videos. http://nuxcmcwkit:8899/TestSuite/EME_MSE/Clear_key_encryption/clear_key_encoding_mp4.html

The key can be hard coded directly in the javascript : // Define a key: hardcoded in this example – this corresponds to the key used for encryption var KEY = new Uint8Array([ /* 0x9A, 0x04, 0xF0, 0x79, 0x98, 0x40, 0x42, 0x86, 0xAB, 0x92, 0xE6, 0x5B, 0xE0, 0x88, 0x5F, 0x95 */

/* 0x04, 0x71, 0x4B, 0xD8, 0xD7, 0xE1, 0xF3, 0x81, 0x5F, 0xC4, 0x7D, 0x0A, 0x83, 0x4F, 0x0E, 0x17 */ 0x88, 0x14, 0x94, 0xBC, 0x53, 0xA4, 0x89, 0x47, 0x9F, 0x26, 0x7A, 0x52, 0x1C, 0x9F, 0xE3, 0x43 ]);

And key wrapping is managed as following: var keyObj = { kty: 'oct', alg: 'A128KW', kid: request.kids[0], k: toBase64(KEY) }; It seems the key is not correct to decrypt the video There is an error in inspector.

There is an algorithm to get generated play ready content key, given by microsoft. Shall we implement it , according to the inputs from xml file ?

byte[] GeneratePlayReadyContentKey(byte[] keySeed, Guid keyId) { const int DRM_AES_KEYSIZE_128 = 16; byte[] contentKey = new byte[DRM_AES_KEYSIZE_128]; // // Truncate the key seed to 30 bytes, key seed must be at least 30 bytes long. // byte[] truncatedKeySeed = new byte[30]; Array.Copy(keySeed, truncatedKeySeed, truncatedKeySeed.Length); // // Get the keyId as a byte array // byte[] keyIdAsBytes = keyId.ToByteArray(); // // Create sha_A_Output buffer. It is the SHA of the truncatedKeySeed and the keyIdAsBytes

// SHA256Managed sha_A = new SHA256Managed(); sha_A.TransformBlock(truncatedKeySeed, 0, truncatedKeySeed.Length, truncatedKeySeed, 0); sha_A.TransformFinalBlock(keyIdAsBytes, 0, keyIdAsBytes.Length); byte[] sha_A_Output = sha_A.Hash; // // Create sha_B_Output buffer. It is the SHA of the truncatedKeySeed, the keyIdAsBytes, and // the truncatedKeySeed again. // SHA256Managed sha_B = new SHA256Managed(); sha_B.TransformBlock(truncatedKeySeed, 0, truncatedKeySeed.Length, truncatedKeySeed, 0); sha_B.TransformBlock(keyIdAsBytes, 0, keyIdAsBytes.Length, keyIdAsBytes, 0); sha_B.TransformFinalBlock(truncatedKeySeed, 0, truncatedKeySeed.Length); byte[] sha_B_Output = sha_B.Hash; // // Create sha_C_Output buffer. It is the SHA of the truncatedKeySeed, the keyIdAsBytes, // the truncatedKeySeed again, and the keyIdAsBytes again. // SHA256Managed sha_C = new SHA256Managed(); sha_C.TransformBlock(truncatedKeySeed, 0, truncatedKeySeed.Length, truncatedKeySeed, 0); sha_C.TransformBlock(keyIdAsBytes, 0, keyIdAsBytes.Length, keyIdAsBytes, 0); sha_C.TransformBlock(truncatedKeySeed, 0, truncatedKeySeed.Length, truncatedKeySeed, 0); sha_C.TransformFinalBlock(keyIdAsBytes, 0, keyIdAsBytes.Length); byte[] sha_C_Output = sha_C.Hash; for (int i = 0; i < DRM_AES_KEYSIZE_128; i++) { contentKey[i] = Convert.ToByte(sha_A_Output[i] ^ sha_A_Output[i + DRM_AES_KEYSIZE_128] ^ sha_B_Output[i] ^ sha_B_Output[i + DRM_AES_KEYSIZE_128] ^ sha_C_Output[i] ^ sha_C_Output[i + DRM_AES_KEYSIZE_128]); } return contentKey; }

There are some issues on Media Keys on DOM. This script perfectly works on a WebM file from google : Good key : http://nuxcmcwkit:8899/TestSuite/EME_MSE/Clear_key_encryption/clear_key_encoding_webm.html: Video is correctly decoded Bad key: http://nuxcmcwkit:8899/TestSuite/EME_MSE/Clear_key_encryption/clear_key_encoding_webm_bad_key.html: Video is not visible and there is an Event error

In chrome inspector , comparing the case when the video decoding is Ok and KO :

In case the key to decode the webm video is not correct, we have following traces :

So the error is different: In case of trying to read a Webm video with bad key, javascript code tries to get the key from licence and find the key is not correct. In the case of trying to read a mp4 video crypted with MP4Box, the error is in the DOM and deals with media keys.

=> Seems the way to encrypt the video is not OK.

2°) Using dash.js Now, trying to play the encrypted video as a dash video, using dash.js :

http://nuxcmcwkit:8899/TestSuite/EME_MSE/DASH_JS/samples/dash-if-reference-player/index_bis.html

with a modification to point on specific mpd file :

see: http://nuxcmcwkit:8899/TestSuite/EME_MSE/DASH_JS/samples/dash-if-reference-player/app/sources_bis.json

There are also some issues, on events: