Menu

#19 Clear key encoding with MP4 has not expected header

v1.0 (example)
open
clear key (1)
5
2015-08-21
2015-07-09
ljl
No

Hi,

I managed following sequence :

MP4Box -v -crypt drm_file_play_ready.xml big_buck_bunny.mp4 -out encoded_big_buck_bunny.mp4
I attach different files for information.

Using playreadyKeyGen.java, i got the correspondence between UUID key and needed elements for xml files:

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)
===============================================
I can check the video encoded_big_buck_bunny.mp4 is crypted.

Now, the problem i have, is to decrypt it using javascript .

Using youtube MSE/EME tests developped by google,
script says the header has not correct format : WidWine header is detected.

  • Extracts the BMFF Clear Key ID from the init data of the segment.
  • @param {ArrayBuffer} initData Init data for the media segment.
  • @return {ArrayBuffer} Returns the BMFF ClearKey ID if found, otherwise the
  • initData itself.

    // Scan for Clear Key header
    if ((dv.getUint32(pos + 12, false) == 0x58147ec8) &&
    (dv.getUint32(pos + 16, false) == 0x04234659) &&
    (dv.getUint32(pos + 20, false) == 0x92e6f52c) &&
    (dv.getUint32(pos + 24, false) == 0x5ce8c3cc)) {
    var size = dv.getUint32(pos + 28, false);
    if (size != 16) throw 'Unexpected KID size ' + size;
    return new Uint8Array(abuf.slice(pos + 32, pos + 32 + size));
    }

    // Failing that, scan for Widevine protobuf header
    if ((dv.getUint32(pos + 12, false) == 0xedef8ba9) &&
    (dv.getUint32(pos + 16, false) == 0x79d64ace) &&
    (dv.getUint32(pos + 20, false) == 0xa3c827dc) &&
    (dv.getUint32(pos + 24, false) == 0xd51d21ed)) {
    return new Uint8Array(abuf.slice(pos + 36, pos + 52));

And i have :

(dv.getUint32(pos + 12, false))
3991899049 <--> EDEF8BA9
(dv.getUint32(pos + 16, false))
2044086990 <--> 79D64ACE
(dv.getUint32(pos + 20, false))
2747803612 <--> A3C827DC
(dv.getUint32(pos + 24, false))
3575456237 <--> D51D21ED

which is widewine .

javascript inspector gives also :

key -> OK
[136, 20, 148, 188, 83, 164, 137, 71, 159, 38, 122, 82, 28, 159, 227, 67]

kid not good as it takes the value from header widewine
[103, 7, 13, 215, 126, 214, 95, 34, 174, 40, 71, 38, 223, 134, 247, 127]

this.keySystem
"webkit-org.w3.clearkey"

Can you please comment ?

Did i make an error in the clear key encoding ?
i join the files i have used.

1 Attachments

Discussion

  • ljl

    ljl - 2015-07-09

    drm_file_play-ready.xml as the good header :
    PlayReady SystemID is used: 9a04f07998404286ab92e65be0885f95

    <GPACDRM type="CENC AES-CTR"> <DRMInfo type="pssh" version="0"> <BS ID128="9a04f07998404286ab92e65be0885f95"/> <BS bits="32" value="764" endian="little"/> <BS bits="16" value="1" endian="little"/> <BS bits="16" value="1" endian="little"/> <BS bits="16" value="758" endian="little"/> <BS dataFile="playready_wrm_v4100_utf16.xml" dataLength="0"/> </DRMInfo> <CrypTrack trackID="2" IsEncrypted="1" IV_size="16" first_IV="0x6403E7BBEBA1B785" saiSavedBox="senc"> <key KID="0x20000000200020002000200000000002" value="0x881494BC53A489479F267A521C9FE343"/> </CrypTrack> </GPACDRM>

    playready_wrm_v4100_utf16 is:

    <WRMHEADER version="4.1.0.0" xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader">
    <DATA>
    <KID value="AAAAIAAgACAgACAAAAAAAg==" ALGID="AESCTR" CHECKSUM="fm+3IvdgFnU="/>
    <LA_URL>http://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&UseSimpleNonPersistentLicense=1</LA_URL>
    </DATA>
    </WRMHEADHER>

     

    Last edit: ljl 2015-07-09
  • Romain Bouqueau

    Romain Bouqueau - 2015-07-09

    Ummm... before a CENC expert answers, I have the feeling the inconsistency you describe is due to the Java file, which is not part of GPAC. Have you reported it to https://github.com/cablelabs/mse-eme also?

     
  • ljl

    ljl - 2015-07-10

    Hi,

    I have asked some support to cablelabs (Greg Rutz).

    It seems they find similar issue in BMFF generation.

    see http://sourceforge.net/p/gpac/discussion/287547/thread/a26422d3/

    I have a question :

    To validate the tools, i tried to manage widevine encryption (that is also supported by youtube EME/MSE tests).

    The java CryptfileGen for widevine gives following output :

    Request Message:
    {
    "content_id": "MQ==",
    "policy": "",
    "drm_types":
    "WIDEVINE"
    ,
    "tracks":
    {
    "type": "HD"
    }

    }
    Request:
    {
    "request": "eyJjb250ZW50X2lkIjoiTVE9PSIsInBvbGljeSI6IiIsImRybV90eXBlcyI6WyJXSURFVklORSJdLCJ0cmFja3MiOlt7InR5cGUiOiJIRCJ9XX0=",
    "signer": "widevine_test"
    }
    Sending HTTP POST to https://license.uat.widevine.com/cenc/getcontentkey/widevine_test
    Received response code -- 200
    Response:
    {
    "response": "eyJzdGF0dXMiOiJPSyIsImRybSI6W3sidHlwZSI6IldJREVWSU5FIiwic3lzdGVtX2lkIjoiZWRlZjhiYTk3OWQ2NGFjZWEzYzgyN2RjZDUxZDIxZWQifV0sInRyYWNrcyI6W3sidHlwZSI6IkhEIiwia2V5X2lkIjoiSllCRTYvcXNWbHFvVCtkZ0dwYXRFUT09Iiwia2V5IjoiYzZLa0hjMFp4TnFBNU5RWllVU2VsQT09IiwicHNzaCI6W3siZHJtX3R5cGUiOiJXSURFVklORSIsImRhdGEiOiJDQUVTRUNXQVJPdjZyRlphcUUvbllCcVdyUkVhRFhkcFpHVjJhVzVsWDNSbGMzUWlBVEVxQWtoRU1nQT0ifV19XSwiYWxyZWFkeV91c2VkIjp0cnVlfQ=="
    }
    ResponseMessage:
    {
    "status": "OK",
    "drm":
    {
    "type": "WIDEVINE",
    "system_id": "edef8ba979d64acea3c827dcd51d21ed"
    }
    ,
    "tracks":
    {
    "pssh": [
    {
    "drm_type": "WIDEVINE",
    "data": "CAESECWAROv6rFZaqE/nYBqWrREaDXdpZGV2aW5lX3Rlc3QiATEqAkhEMgA="
    }
    ,
    "key_id": "JYBE6/qsVlqoT+dgGpatEQ==",
    "type": "HD",
    "key": "c6KkHc0ZxNqA5NQZYUSelA=="
    }
    ],
    "already_used": true
    }
    <GPACDRM type="CENC AES-CTR">
    <CrypTrack IV_size="8" first_IV="0xe5ae3102fd8a696b" isEncrypted="1" saiSavedBox="senc" trackID="2">
    <key KID="0x258044ebfaac565aa84fe7601a96ad11" value="0x73a2a41dcd19c4da80e4d41961449e94"/>
    </CrypTrack>
    </GPACDRM>

    and i put

    <GPACDRM type="CENC AES-CTR">
    <CrypTrack IV_size="8" first_IV="0xe5ae3102fd8a696b" isEncrypted="1" saiSavedBox="senc" trackID="2">
    <key KID="0x258044ebfaac565aa84fe7601a96ad11" value="0x73a2a41dcd19c4da80e4d41961449e94"/>
    </CrypTrack>
    </GPACDRM>

    as input to encrypt the video.

    Then i use keyId (0x258044ebfaac565aa84fe7601a96ad11) and Keyvalue (0x73a2a41dcd19c4da80e4d41961449e94) in javascript to decrypt the video.
    I have still issues.

    Is the CENC AES-CTR xml file input correct ?
    Do i need to add data ...
    Have you already tested the MSE decryption using MP4Box ?

    Thanks

    Regards

     

    Last edit: ljl 2015-07-10
  • ljl

    ljl - 2015-07-16

    Hi,

    I try to encode using MP4Box (version 0.5.2) a clear video from youtube test wich video type is :

    And I have an error : Segmentation fault.

    The parameters I use are :

    /a/opt.softs/workshop/4.0/bin/MP4Box -v -crypt clear_key_crypt.xml initial_video.mp4 -out encoded_video.mp4

    With : clear_key_crypt.xml

    <GPACDRM type="CENC AES-CTR">
    <DRMInfo type="pssh" version="1">
    <BS ID128="1077efecc0b24d02ace33c1e52e2fb4b"/>
    <BS bits="32" value="1"/>
    <BS ID128="20000000200020002000200000000002"/>
    </DRMInfo>
    <CrypTrack IV_size="8" first_IV="0x11586318e7c5b9d4" isEncrypted="1" saiSavedBox="senc" trackID="2">
    <key KID="0x20000000200020002000200000000002" value="0x5d83c30aa76d60b25a0af1b84e0b1d95"/>
    </CrypTrack>
    </GPACDRM>

    This error does not occur for big_buck_bunny_video.mp4 which has a different codec encoding.

    Do you have an idea of what the problem can be ?

    Thanks

    Regards

     
  • ljl

    ljl - 2015-07-16

    Hi,

    Thanks for the correction.

    Is there a binary i can take with this fix ?

    thanks

    Regards

     
  • Romain Bouqueau

    Romain Bouqueau - 2015-07-16

    Yes, gpac-0.5.2-DEV-rev534-g2cc7d80 from http://gpac.io/downloads/gpac-nightly-builds/

     
  • ljl

    ljl - 2015-07-16

    Hi,

    I have an other issue.

    I tried to encrypt following video () using MP4Box.
    Then i play the encrypted video using youtube tests.

    the xml file passed to mP4Box has following value :

    <GPACDRM type="CENC AES-CTR"> <DRMInfo type="pssh" version="0"> <BS ID128="1077efecc0b24d02ace33c1e52e2fb4b"/> <BS bits="32" value="1"/> <BS ID128="20000000200020002000200000000002"/> </DRMInfo> <CrypTrack IV_size="8" first_IV="0x11586318e7c5b9d4" isEncrypted="1" saiSavedBox="senc" trackID="1"> <key KID="0x20000000200020002000200000000002" value="0x5d83c30aa76d60b25a0af1b84e0b1d95"/> </CrypTrack> </GPACDRM>

    And i have following error :

    Uncaught Cannot find sidx box in first 47181595 bytes of file.

    The video has a avc1.4d401f codec

    What does this error mean ?

    thanks

    Regards

     
  • ljl

    ljl - 2015-08-21

    Hi,

    I have now used following url from google : http://shaka-player-demo.appspot.com/, which seems to be a more complete player for EME/MSE encrypted videos.

    And get mp4 videos from http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-manifest.mpd

    That are clear videos and can be played on google chrome in DASH mode
    http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-85.mp4
    http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-86.mp4
    http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-87.mp4
    http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-88.mp4
    http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-89.mp4
    http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-160.mp4

    Those videos are clear video (I can play them using google chrome) and I get some information on them using MP4Box:

    For instance :

    /a/opt.softs/workshop/4.0/bin/MP4Box -info ../ClearVideos/car-20120827-85.mp4

    • Movie Info *
      Timescale 90000 - Duration 00:00:00.000
      1 track(s)
      Fragmented File: yes - duration 00:00:00.000
      37 fragments - 1 SegmentIndexes
      File suitable for progressive download (moov before mdat)
      File Brand dash - version 0
      Created: GMT Mon Aug 27 01:00:50 2012
      Modified: GMT Mon Aug 27 01:00:50 2012

    File has no MPEG4 IOD/OD

    Track # 1 Info - TrackID 1 - TimeScale 90000 - Media Duration 00:00:00.000
    Media Info: Language "und (und)" - Type "vide:avc1" - 0 samples
    Fragmented track: 4350 samples - Media Duration 00:03:01.443
    Visual Track layout: x=0 y=0 width=426 height=240
    MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x21
    AVC/H264 Video - Visual Size 426 x 240
    AVC Info: 1 SPS - 1 PPS - Profile Main @ Level 2.1
    NAL Unit length bits: 32
    SPS#1 hash: 25B2F0F663A8ED3C2339605F43A08CC2F15F70DB
    PPS#1 hash: 6B44EFFCD177F42E94F8AB3946CE5AD74269431F
    Self-synchronized
    RFC6381 Codec Parameters: avc1.4d4015
    No sync sample found

    Then I have crypted those videos using MP4Box:

    /a/opt.softs/workshop/4.0/bin/MP4Box -v -crypt clear_key_encrypt.xml ../ClearVideos/car-20120827-85.mp4 -out clear_key_enc_mp4box_car-20120827-85.mp4

    The xml file has following values :

    <GPACDRM type="CENC AES-CTR"> <DRMInfo type="pssh" version="0"> <BS ID128="1077efecc0b24d02ace33c1e52e2fb4b"/> <BS bits="32" value="1"/> <BS ID128="20000000200020002000200000000002"/> </DRMInfo> <CrypTrack IV_size="8" first_IV="0x11586318e7c5b9d4" isEncrypted="1" saiSavedBox="senc" trackID="1"> <key KID="0x20000000200020002000200000000002" value="0x5d83c30aa76d60b25a0af1b84e0b1d95"/> </CrypTrack> </GPACDRM>

    As a result I can check the video is encrypted :

    Check info

    /a/opt.softs/workshop/4.0/bin/MP4Box -v -info clear_key_enc_mp4box_car-20120827-85.mp4

    *Encrypted stream - CENC scheme cenc (version 65536)
    Initialization Vector size: 64 bits
    RFC6381 Codec Parameters: avc1.4d4015
    Average GOP length: 63 samples

    Then, I replaced the mpd file used by http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-manifest.mpd
    With my encrypted videos : clear_key_enc_mp4box_car-20120827-manifest.mpd (In this way, I have the same mp4 codecs)

    It has following aspect :

    <MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" mediaPresentationDuration="PT0H3M1.63S" minBufferTime="PT1.5S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static">
    <BaseURL>http://nuxcmcwkit:8899/TestSuite/</BaseURL>
    <Period duration="PT0H3M1.63S" start="PT0S">
    <AdaptationSet>
    <ContentComponent contentType="video" id="1"/>
    <ContentProtection schemeIdUri="com.youtube.clearkey">
    <ytdrm:License keyid="20000000200020002000200000000002" key="5d83c30aa76d60b25a0af1b84e0b1d95"/>
    </ContentProtection>
    <Representation bandwidth="4190760" codecs="avc1.640028" height="1080" id="1" mimeType="video/mp4" width="1920">
    <BaseURL>EME_MSE/shaka_player/ClearKeyMp4BoxVideos/clear_key_enc_mp4box_car-20120827-89.mp4</BaseURL>
    <SegmentBase indexRange="674-1149">
    <Initialization range="0-673"/>
    </SegmentBase>
    </Representation>
    <Representation bandwidth="2073921" codecs="avc1.4d401f" height="720" id="2" mimeType="video/mp4" width="1280">
    <BaseURL>EME_MSE/shaka_player/ClearKeyMp4BoxVideos/clear_key_enc_mp4box_car-20120827-88.mp4</BaseURL>
    <SegmentBase indexRange="708-1183">
    <Initialization range="0-707"/>
    </SegmentBase>
    </Representation>
    <Representation bandwidth="869460" codecs="avc1.4d401e" height="480" id="3" mimeType="video/mp4" width="854">
    <BaseURL>EME_MSE/shaka_player/ClearKeyMp4BoxVideos/clear_key_enc_mp4box_car-20120827-87.mp4</BaseURL>
    <SegmentBase indexRange="708-1183">
    <Initialization range="0-707"/>
    </SegmentBase>
    </Representation>
    <Representation bandwidth="686521" codecs="avc1.4d401e" height="360" id="4" mimeType="video/mp4" width="640">
    <BaseURL>EME_MSE/shaka_player/ClearKeyMp4BoxVideos/clear_key_enc_mp4box_car-20120827-86.mp4</BaseURL>
    <SegmentBase indexRange="708-1183">
    <Initialization range="0-707"/>
    </SegmentBase>
    </Representation>
    <Representation bandwidth="264835" codecs="avc1.4d4015" height="240" id="5" mimeType="video/mp4" width="426">
    <BaseURL>EME_MSE/shaka_player/ClearKeyMp4BoxVideos/clear_key_enc_mp4box_car-20120827-85.mp4</BaseURL>
    <SegmentBase indexRange="672-1147">
    <Initialization range="0-671"/>
    </SegmentBase>
    </Representation>
    <Representation bandwidth="100000" codecs="avc1.4d4015" height="144" id="5" mimeType="video/mp4" width="256">
    <BaseURL>EME_MSE/shaka_player/ClearKeyMp4BoxVideos/clear_key_enc_mp4box_car-20120827-160.mp4</BaseURL>
    <SegmentBase indexRange="671-1146">
    <Initialization range="0-670"/>
    </SegmentBase>
    </Representation>
    </AdaptationSet>
    </Period>
    </MPD>

    And I add this manifest to shake player .

    Playing those encrypted videos I can see following errors :

    Invalid box type, expected "sidx".
    Player error CustomEvent {detail: Error: Failed to parse segment references from
    at null.<anonymous> (http://nuxcmcwkit:8899/TestS…, srcElement: null, target: s…a.p…r.Player, currentTarget: s…a.p…r.Player}

    Now, analysing the encrypted video using http://mp4parser.com/,

    I can see the initial video has sidx:

    0 1c ftyp
    1c 2a8 moov
    2c4 1dc sidx
    4a0 5f8 moof
    a98 a9619 mdat
    aa0b1 5f8 moof
    aa6a9 a7382 mdat
    151a2b 5f8 moof
    152023 886a9 mdat
    1da6cc 5f8 moof
    1dacc4 52006 mdat
    22ccca 5

    But no the clear key MP4Box encrypted video :

    0 1c ftyp
    1c 1e9fd moov
    1ea19 5b2d61 mdat
    5d177a 4a free

    • Do you know why ?
    • Is there a bug in the tool ?
    • Did i miss something ?

    thanks

    Regards

     

    Last edit: ljl 2015-08-21

Log in to post a comment.