Separate Delivery Encoding Class
// will encode mp3 / wav / jpeg / any media files into Separate Delivery DRM encoding
// http://www.openmobilealliance.org/Technical/release_program/drm_v1_0.aspx
// require mcrypt module
<?php
class SeparateDelivery
{
var $version = 1;
var $content_type = '';
var $content_id = '';
var $headers = 'Encryption-Method: AES128CBC;padding=RFC2630';
function encode($content_id, $content_type, $data, $key='', $headers='')
{
$this->content_id = $content_id;
$this->content_type = $content_type;
if ($headers)
{
$this->headers .= "\r\n" . $headers;
}
$this->initkey($key);
$data = $this->encrypt($data);
$output = pack('CCC', $this->version, strlen($this->content_type), strlen($this->content_id));
$output .= $this->content_type;
$output .= $this->content_id;
$output .= $this->pack_uintvar(strlen($this->headers));
$output .= $this->pack_uintvar(strlen($data));
$output .= $this->headers;
$output .= $data;
return $output;
}
function pack_uintvar($bval)
{
$pck = '';
do
{
$sept = $bval & 0x7F;
$bval = $bval >> 7;
$pck = pack('C', $sept | ((strlen($pck) > 0) ? 0x80 : 0) ) . $pck;
}
while ($bval > 0);
return $pck;
}
function initkey($key='')
{
if (!isset($this->key))
{
$this->key = '';
$keysize = mcrypt_module_get_algo_key_size(MCRYPT_RIJNDAEL_128);
if (($keysize > 0) && ($td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '')))
{
$keysize = 16;
while (strlen($key) < $keysize)
{
$key .= mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
}
mcrypt_module_close($td);
$key = substr($key, 0, $keysize);
$this->key = $key;
}
}
return $this->key;
}
function encrypt($data)
{
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
$this->iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $this->key, $this->iv);
// padding
$bs = mcrypt_enc_get_block_size($td);
$plen = $bs - (strlen($data) % $bs);
for($i = 0; $i < $plen; $i++)
$data .= pack('C', $plen);
$encrypted_data = $this->iv.mcrypt_generic($td, $data);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $encrypted_data;
}
function decrypt($data)
{
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
$iv_length = mcrypt_enc_get_iv_size($td);
$this->iv = substr($data, 0, $iv_length);
$data = substr($data, $iv_length);
mcrypt_generic_init($td, $this->key, $this->iv);
$decrypted_data = mdecrypt_generic($td, $data);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
// remove padding
$dataLen = strlen($decrypted_data);
$paddingLength = substr($decrypted_data, $dataLen - 1, 1);
$decrypted_data = substr($decrypted_data, 0, $dataLen - ord($paddingLength));
return $decrypted_data;
}
function hex_dump($data)
{
$hexi = '';
$i = 0;
while ($i < strlen($data))
{
$hexi .= sprintf("%02X", ord($data{$i}));
$i++;
}
return $hexi;
}
}
?>
// example
<?php
$sd = new SeparateDelivery;
$result = $sd->encode('cid:ferdhie@id-snippet.com', 'image/jpeg',
file_get_contents('test.jpg'),
base64_decode('Lsaip8QiFAdSfevcR8GzIA=='));
$fp = fopen('test2.dcf', 'wb');
fputs($fp, $result);
fclose($fp);
?>
0 Comments