View Single Post
  #13  
Old 04-20-2012, 11:42 AM
KSV KSV is offline
Senior Member
 
Join Date: Apr 2011
Posts: 853
KSV is on a distinguished road
Cool

Re: Record Pluzz.fr from linux


Quote:
Originally Posted by bibichouchou View Post
Shortly, you have to retrieve part of the FLV header from the manifest file. There are in general, 3 different video qualities and for each you have (part of) the FLV header encrypted (one can use the base64 python package to decode it).
Then you have to strip the first bytes of the fragments before concatenating them (see the Pluzzdl.py in the package I pointed for more details). Let me know if you don't find the code snippet... I reassure you I don't want to broadcast it on my webpage. Besides, i don't have time to have a webpage
i was aware of flv header and base64 decoding of bootstrap info (it's just Metadata tag anyway) but i was hoping for proper decoder for mp4 boxes to recover flv data. script just uses a single regexp to find mdat+79 offset and copies all remaining data. it's very crude way to parse things but whatever works is good enough to be of some use

so here is the procedure to retrieve secured fragments. each fragment request is accompanied by four security parameters.
Code:
http://ftvodhdsecz-f.akamaihd.net//z/streaming-adaptatif/2012/S16/J4/62158719-20120419-,398,632,934,k.mp4.csmil/1_e8775c2b4acd5464_Seg1-Frag1?
pvtoken=st=0000000000~exp=9999999999~acl=%2f%2a~data=ZXhwPTEzMzUwMDgzNzJ+YWNsPSUyZip+ZGF0YT1wdmMsc35obWFjPWU0NjFkYjYyZjQ5ZjgzYzZiMGQxYjk4NjNmZjBmZmY1MjE0MTAyOThkZGQyMzVmOGVjNGM4ZmE4MGI0NGJiNDY=!3fPHzcjMxiTmRj5AdV0bhzgjjSjk2PqUMBzFxgPEPF4=~hmac=4A196FC74660DCDBD39045827F28007296177A0FD25B36A6AB4359C69FDA82E3&
hdntl=exp=1335008372~acl=/z/streaming-adaptatif/2012/S16/J4/62158719-20120419-*~data=hdntl~hmac=21194bf78c5f22813096932f4db484890087fc34ee5aad9b2449ee1044b788d4&
hdnea=exp=1334922570~acl=/z/streaming-adaptatif/2012/S16/J4/62158719-20120419-*~hmac=48fe0fa3a50155abb1aa96c472d81b58b6d497fd01c7f79744e099643888dfee&
als=0,0.1,0,1,0,NaN,0,0,0,18,f,0,2759.58,f,s,DUNCYBSALHLK,2.6.9,18
als parameter is useless and can be omitted. it's just bandwidth metering and analytics stuff. hdnea and hdntl parameters can be easily retrieved from server.

hdnea:
Code:
http://hdfauth.francetv.fr/esi/urltokengen2.html?url=/z/streaming-adaptatif/2012/S16/J4/62158719-20120419-,398,632,934,k.mp4.csmil/manifest.f4m
Code:
http://ftvodhdsecz-f.akamaihd.net//z/streaming-adaptatif/2012/S16/J4/62158719-20120419-,398,632,934,k.mp4.csmil/manifest.f4m?hdnea=exp=1334942910~acl=%2fz%2fstreaming-adaptatif%2f2012%2fS16%2fJ4%2f62158719-20120419-*~hmac=6eadf2821bfd4b55663fc7f09e3508135d274a85960604f3d9dd7d646ed47ad0
hdntl:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns="http://ns.adobe.com/f4m/1.0" xmlns:akamai="uri:akamai.com/f4m/1.0">
  <akamai:bw>1000</akamai:bw>
  <id>/streaming-adaptatif/2012/S16/J4/62158719-20120419-,398,632,934,k.mp4.csmil_0</id>
  <streamType>recorded</streamType>
  <duration>2759.575</duration>
  <streamBaseTime>0.000</streamBaseTime>
  <pv-2.0>ZXhwPTEzMzUwMjcwNjN+YWNsPSUyZip+ZGF0YT1wdmMsc35obWFjPTBhNjViYjAyOTAwZGYxZDg2MmRmZTkyZWUzMzkwZTNkZjA2ZWZjMTE1OTQ5MDBlOTYxZmI1NDVjNjdhNDgxMTA=;hdntl=exp=1335027063~acl=%2fz%2fstreaming-adaptatif%2f2012%2fS16%2fJ4%2f62158719-20120419-*~data=hdntl~hmac=fa73dd53c60993d1bc0234b0a71697dd2e9b71afe305319620f8569daafc5e69</pv-2.0>
  <bootstrapInfo profile="named" id="bootstrap_0">AAAAi2Fic3QAAAAAAAAAAQAAAAPoAAAAAAAqG5cAAAAAAAAAAAAAAAAAAQAAABlhc3J0AAAAAAAAAAABAAAAAQAAAcwBAAAARmFmcnQAAAAAAAAD6AAAAAADAAAAAQAAAAAAAAAAAAAXcAAAAcwAAAAAACoF0AAAFccAAAAAAAAAAAAAAAAAAAAAAA==</bootstrapInfo>
  <bootstrapInfo profile="named" id="bootstrap_1">AAAAi2Fic3QAAAAAAAAAAQAAAAPoAAAAAAAqG5cAAAAAAAAAAAAAAAAAAQAAABlhc3J0AAAAAAAAAAABAAAAAQAAAcwBAAAARmFmcnQAAAAAAAAD6AAAAAADAAAAAQAAAAAAAAAAAAAXcAAAAcwAAAAAACoF0AAAFccAAAAAAAAAAAAAAAAAAAAAAA==</bootstrapInfo>
  <bootstrapInfo profile="named" id="bootstrap_2">AAAAi2Fic3QAAAAAAAAAAQAAAAPoAAAAAAAqG5cAAAAAAAAAAAAAAAAAAQAAABlhc3J0AAAAAAAAAAABAAAAAQAAAcwBAAAARmFmcnQAAAAAAAAD6AAAAAADAAAAAQAAAAAAAAAAAAAXcAAAAcwAAAAAACoF0AAAFccAAAAAAAAAAAAAAAAAAAAAAA==</bootstrapInfo>
  <media bitrate="301" url="0_e8775c2b4acd5464_" bootstrapInfoId="bootstrap_0">
    <metadata>AgAKb25NZXRhRGF0YQgAAAAMAAhkdXJhdGlvbgBApY8mZmZmZgAFd2lkdGgAQHQAAAAAAAAABmhlaWdodABAZgAAAAAAAAANdmlkZW9kYXRhcmF0ZQBAboAAAAAAAAAJZnJhbWVyYXRlAEA5AAAAAAAAAAx2aWRlb2NvZGVjaWQAQBwAAAAAAAAADWF1ZGlvZGF0YXJhdGUAQEyAAAAAAAAAD2F1ZGlvc2FtcGxlcmF0ZQBB5YiAAAAAAAAPYXVkaW9zYW1wbGVzaXplAEAwAAAAAAAAAAZzdGVyZW8BAQAMYXVkaW9jb2RlY2lkAEAkAAAAAAAAAAhmaWxlc2l6ZQBBmMPPTAAAAAAAAw==</metadata>
  </media>
  <media bitrate="572" url="1_e8775c2b4acd5464_" bootstrapInfoId="bootstrap_1">
    <metadata>AgAKb25NZXRhRGF0YQgAAAAMAAhkdXJhdGlvbgBApY8mZmZmZgAFd2lkdGgAQIAAAAAAAAAABmhlaWdodABAcgAAAAAAAAANdmlkZW9kYXRhcmF0ZQBAgBgAAAAAAAAJZnJhbWVyYXRlAEA5AAAAAAAAAAx2aWRlb2NvZGVjaWQAQBwAAAAAAAAADWF1ZGlvZGF0YXJhdGUAQEyAAAAAAAAAD2F1ZGlvc2FtcGxlcmF0ZQBB5YiAAAAAAAAPYXVkaW9zYW1wbGVzaXplAEAwAAAAAAAAAAZzdGVyZW8BAQAMYXVkaW9jb2RlY2lkAEAkAAAAAAAAAAhmaWxlc2l6ZQBBp4Fu5AAAAAAAAw==</metadata>
  </media>
  <media bitrate="828" url="2_e8775c2b4acd5464_" bootstrapInfoId="bootstrap_2">
    <metadata>AgAKb25NZXRhRGF0YQgAAAAMAAhkdXJhdGlvbgBApY8mZmZmZgAFd2lkdGgAQIYAAAAAAAAABmhlaWdodABAeQAAAAAAAAANdmlkZW9kYXRhcmF0ZQBAiBgAAAAAAAAJZnJhbWVyYXRlAEA5AAAAAAAAAAx2aWRlb2NvZGVjaWQAQBwAAAAAAAAADWF1ZGlvZGF0YXJhdGUAQEyAAAAAAAAAD2F1ZGlvc2FtcGxlcmF0ZQBB5YiAAAAAAAAPYXVkaW9zYW1wbGVzaXplAEAwAAAAAAAAAAZzdGVyZW8BAQAMYXVkaW9jb2RlY2lkAEAkAAAAAAAAAAhmaWxlc2l6ZQBBsQYsjwAAAAAAAw==</metadata>
  </media>
</manifest>
blue part is hdntl parameter and red part is used to generate pvtoken.

pvtoken:
now following is the sample php function to generate pvtoken and sign the request.
Code:
<?php
  echo "\nKSV AkamaiSecureHDS Token Generator\n\n";
  $key     = pack("H*", "bd938d5ee6d9f42016f9c56577b6fdcf415fe4b184932b785ab32bcadc9bb592");
  $pvtoken = base64_encode(pack("H*", "ddf3c7cdc8ccc624e6463e40755d1b8738238d28e4d8fa94301cc5c603c43c5e"));
  $pv_20   = "ZXhwPTEzMzUwMjcwNjN+YWNsPSUyZip+ZGF0YT1wdmMsc35obWFjPTBhNjViYjAyOTAwZGYxZDg2MmRmZTkyZWUzMzkwZTNkZjA2ZWZjMTE1OTQ5MDBlOTYxZmI1NDVjNjdhNDgxMTA=";
  $data    = "st=0000000000~exp=9999999999~acl=%2f%2a~data=" . $pv_20 . "!" . $pvtoken;
  $signed  = hash_hmac("sha256", $data, $key);
  echo "pvtoken=$data~hmac=$signed";
?>
in my quest to solve it the hardest part was to recover the encryption key and algorithm used to sign the pvtoken verification response. blue part is sha256 hash of decompressed player swf. if they upgrade their player you also need to change this. green part is the hmac-sha256 key used to sign the request.
Reply With Quote