function Decrypt($data, $pos, $opt = array()) { /** @var cURL $cc */ $auth = ""; $baseUrl = ""; $cc = null; extract($opt, EXTR_IF_EXISTS); $debug = $this->debug; if ($this->decryptorTest) { $debug = false; } LogDebug("\n----- Akamai Decryption Start -----", $debug); // Parse packet header $byte = ReadByte($data, $pos++); $this->ecmVersion = $byte >> 4; if ($this->ecmVersion != 11) { $this->ecmVersion = $byte; } $this->ecmID = ReadInt32($data, $pos); $this->ecmTimestamp = ReadInt32($data, $pos + 4); $this->kdfVersion = ReadInt16($data, $pos + 8); $pos += 10; $this->dccAccReserved = ReadByte($data, $pos++); LogDebug("ECM Version : " . $this->ecmVersion . ", ECM ID: " . $this->ecmID . ", ECM Timestamp: " . $this->ecmTimestamp . ", KDF Version: " . $this->kdfVersion . ", DccAccReserved: " . $this->dccAccReserved, $debug); $byte = ReadByte($data, $pos++); $iv = ($byte & 2) > 0 ? true : false; $key = ($byte & 4) > 0 ? true : false; if ($iv) { $this->packetIV = substr($data, $pos, 16); $pos += 16; LogDebug("PacketIV : " . hexlify($this->packetIV), $debug); } if ($key) { $this->sessionKeyUrl = ReadString($data, $pos); LogDebug("SessionKeyUrl: " . $this->sessionKeyUrl, $debug); $keyUrl = substr($this->sessionKeyUrl, strrpos($this->sessionKeyUrl, '/')); $this->sessionID = "_" . substr($keyUrl, strlen("/key_")); $keyUrl = JoinUrl($baseUrl, $keyUrl) . $auth; // Download key file if required if ($this->sessionKeyUrl !== $this->lastKeyUrl) { if ($baseUrl == "") { LogDebug("Unable to download session key without manifest url. you must specify it manually using 'adkey' switch.", $debug); } else { if ($cc->get($keyUrl) != 200) { LogError("Failed to download akamai session decryption key"); } $this->sessionKey = $cc->response; LogInfo("SessionKey: " . hexlify($this->sessionKey), $debug); $this->lastKeyUrl = $this->sessionKeyUrl; } } } LogDebug("SessionKey : " . hexlify($this->sessionKey), $debug); $reserved = ReadByte($data, $pos++); $this->packetSalt = substr($data, $pos, 32); $pos += 32; $reservedBlock1 = substr($data, $pos, 20); $reservedBlock2 = substr($data, $pos + 20, 20); $pos += 40; LogDebug("ReservedByte : " . $reserved . ", ReservedBlock1: " . hexlify($reservedBlock1) . ", ReservedBlock2: " . hexlify($reservedBlock2), $debug); // Generate packet decryption key if ($this->sessionKey == "") { LogError("Fragments can't be decrypted properly without corresponding session key.", 2); } $this->KDF(); // Decrypt packet data $encryptedData = substr($data, $pos); LogDebug("EncryptedData: " . hexlify(substr($encryptedData, 0, 64)), $debug); $lastBlockData = substr($encryptedData, $this->decryptBytes); $encryptedData = substr($encryptedData, 0, $this->decryptBytes); $decryptedData = ""; if ($this->decryptBytes > 0) { mcrypt_generic_init($this->aes_cbc, $this->packetKey, $this->packetIV); $decryptedData = mdecrypt_generic($this->aes_cbc, $encryptedData); mcrypt_generic_deinit($this->aes_cbc); } $decryptedData .= $lastBlockData; LogDebug("DecryptedData: " . hexlify(substr($decryptedData, 0, 64)), $debug); LogDebug("----- Akamai Decryption End -----\n", $debug); return $decryptedData; }
public static function generateToken($url) { $url = str_replace('http://redir.atmcdn.pl/http/', '', $url); $SecretKey = 'AB9843DSAIUDHW87Y3874Q903409QEWA'; $iv = 'ab5ef983454a21bd'; $KeyStr = '0f12f35aa0c542e45926c43a39ee2a7b38ec2f26975c00a30e1292f7e137e120e5ae9d1cfe10dd682834e3754efc1733'; $salt = ''; for ($i = 0; $i < 16; $i++) { $salt .= chr(mt_rand(ord('a'), ord('z'))); } $salt = hexlify($salt); $expire = 3600000 + time() * 1000 - 946684800000; $td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv); mcrypt_generic_init($td, $SecretKey, $iv); $decrypted = mdecrypt_generic($td, unhexlify($KeyStr)); mcrypt_generic_deinit($td); mcrypt_module_close($td); $key = utf8_encode(trim($decrypted)); $unencryptedToken = "name=" . $url . "&expire=" . $expire . ""; $pad = ''; $xx = 16 - strlen($unencryptedToken) % 16; for ($a = 1; $a <= $xx; $a++) { $pad .= chr(16 - strlen($unencryptedToken) % 16); } $unencryptedToken = $unencryptedToken . $pad; $td = mcrypt_module_open('rijndael-128', '', 'cbc', unhexlify($salt)); mcrypt_generic_init($td, unhexlify($key), unhexlify($salt)); $encrypted = mcrypt_generic($td, $unencryptedToken); mcrypt_generic_deinit($td); mcrypt_module_close($td); $token = strtoupper(hexlify($encrypted)); return "http://redir.atmcdn.pl/http/{$url}?salt={$salt}&token={$token}"; }
$dataLength = ReadInt32($decTable, $decPos + 5); $decPos += 9; if ($encrypted) { $rawLength = ReadInt32($decTable, $decPos); $decPos += 4; } else { $rawLength = $dataLength; } LogDebug("Time: {$time}, DataLength: {$dataLength}, RawLength: {$rawLength}"); // Decrypt encrypted tags $data = substr($file, $filePos, $dataLength); if ($encrypted) { LogDebug("Encrypted Packet: " . hexlify($data)); mcrypt_generic_init($td, $key, $iv); $data = mdecrypt_generic($td, $data); LogDebug("Decrypted Packet: " . hexlify($data)); $data = substr($data, 0, $rawLength); } // Create video tag if ($type == 1) { // Create codec tag if ($version == 2) { $codecTag = " "; WriteByte($codecTag, 0, 7 | ($keyframe ? 16 : 32)); WriteByte($codecTag, 1, $config ? 0 : 1); WriteInt24($codecTag, 2, 0); } else { $codecTag = ""; } // Create flv tag $flvTag = " ";
$range = explode(':', $line, 2); $range = $range[1]; $range = explode('@', trim($range)); $t =& $byteRange[]; $t['start'] = trim($range[1]); $t['len'] = trim($range[0]); } } // Read encryption key $key = file_get_contents($argv[3]); if ($key === false) { die("Failed to open key file."); } $iv = $key; LogDebug("Key: " . hexlify($key)); LogDebug("IV : " . hexlify($iv)); // Retrieve and decrypt encrypted blobs $decData = ""; $td = mcrypt_module_open('rijndael-128', '', 'cbc', ''); mcrypt_generic_init($td, $key, $iv); $input = fopen($argv[2], 'rb'); if ($input === false) { die("Failed to open input file."); } $output = fopen($argv[4], 'wb'); if ($output === false) { die("Failed to open output file."); } foreach ($byteRange as $range) { fseek($input, $range['start']); $encData = fread($input, $range['len']);