Advertisement
cdsatrian

Alpha & Protect PDF file

Jul 9th, 2013
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.72 KB | None | 0 0
  1. <?php
  2. require('fpdf.php');
  3. //=== AlphaPDF class ==
  4. //-- extends this class from FPDF class
  5. class AlphaPDF extends FPDF
  6. {
  7.     var $extgstates;
  8.     function AlphaPDF($orientation='P', $unit='mm', $format='A4')
  9.     {
  10.         parent::FPDF($orientation, $unit, $format);
  11.         $this->extgstates = array();
  12.     }
  13.     function SetAlpha($alpha, $bm='Normal')
  14.     {
  15.         $gs = $this->AddExtGState(array('ca'=>$alpha, 'CA'=>$alpha, 'BM'=>'/'.$bm));
  16.         $this->SetExtGState($gs);
  17.     }
  18.     function AddExtGState($parms)
  19.     {
  20.         $n = count($this->extgstates)+1;
  21.         $this->extgstates[$n]['parms'] = $parms;
  22.         return $n;
  23.     }
  24.     function SetExtGState($gs)
  25.     {
  26.         $this->_out(sprintf('/GS%d gs', $gs));
  27.     }
  28.     function _enddoc()
  29.     {
  30.         if(!empty($this->extgstates) && $this->PDFVersion<'1.4')
  31.             $this->PDFVersion='1.4';
  32.         parent::_enddoc();
  33.     }
  34.     function _putextgstates()
  35.     {
  36.         for ($i = 1; $i <= count($this->extgstates); $i++)
  37.         {
  38.             $this->_newobj();
  39.             $this->extgstates[$i]['n'] = $this->n;
  40.             $this->_out('<</Type /ExtGState');
  41.             foreach ($this->extgstates[$i]['parms'] as $k=>$v)
  42.                 $this->_out('/'.$k.' '.$v);
  43.             $this->_out('>>');
  44.             $this->_out('endobj');
  45.         }
  46.     }
  47.     function _putresourcedict()
  48.     {
  49.         parent::_putresourcedict();
  50.         $this->_out('/ExtGState <<');
  51.         foreach($this->extgstates as $k=>$extgstate)
  52.             $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
  53.         $this->_out('>>');
  54.     }
  55.     function _putresources()
  56.     {
  57.         $this->_putextgstates();
  58.         parent::_putresources();
  59.     }
  60. }
  61. if(function_exists('mcrypt_encrypt'))
  62. {
  63.     function RC4($key, $data)
  64.     {
  65.         return mcrypt_encrypt(MCRYPT_ARCFOUR, $key, $data, MCRYPT_MODE_STREAM, '');
  66.     }
  67. }
  68. else
  69. {
  70.     function RC4($key, $data)
  71.     {
  72.         static $last_key, $last_state;
  73.  
  74.         if($key != $last_key)
  75.         {
  76.             $k = str_repeat($key, 256/strlen($key)+1);
  77.             $state = range(0, 255);
  78.             $j = 0;
  79.             for ($i=0; $i<256; $i++){
  80.                 $t = $state[$i];
  81.                 $j = ($j + $t + ord($k[$i])) % 256;
  82.                 $state[$i] = $state[$j];
  83.                 $state[$j] = $t;
  84.             }
  85.             $last_key = $key;
  86.             $last_state = $state;
  87.         }
  88.         else
  89.             $state = $last_state;
  90.  
  91.         $len = strlen($data);
  92.         $a = 0;
  93.         $b = 0;
  94.         $out = '';
  95.         for ($i=0; $i<$len; $i++){
  96.             $a = ($a+1) % 256;
  97.             $t = $state[$a];
  98.             $b = ($b+$t) % 256;
  99.             $state[$a] = $state[$b];
  100.             $state[$b] = $t;
  101.             $k = $state[($state[$a]+$state[$b]) % 256];
  102.             $out .= chr(ord($data[$i]) ^ $k);
  103.         }
  104.         return $out;
  105.     }
  106. }
  107. //==== FPDF_Protection  class ===
  108. // do this trick:
  109. // -- extends this class from AlphaPDF class not from FPDF class
  110. class FPDF_Protection extends AlphaPDF
  111. {
  112.     var $encrypted = false;
  113.     var $Uvalue;          
  114.     var $Ovalue;          
  115.     var $Pvalue;          
  116.     var $enc_obj_id;      
  117.     function SetProtection($permissions=array(), $user_pass='', $owner_pass=null)
  118.     {
  119.         $options = array('print' => 4, 'modify' => 8, 'copy' => 16, 'annot-forms' => 32 );
  120.         $protection = 192;
  121.         foreach($permissions as $permission)
  122.         {
  123.             if (!isset($options[$permission]))
  124.                 $this->Error('Incorrect permission: '.$permission);
  125.             $protection += $options[$permission];
  126.         }
  127.         if ($owner_pass === null)
  128.             $owner_pass = uniqid(rand());
  129.         $this->encrypted = true;
  130.         $this->padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
  131.                         "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
  132.         $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
  133.     }
  134.     function _putstream($s)
  135.     {
  136.         if ($this->encrypted) {
  137.             $s = RC4($this->_objectkey($this->n), $s);
  138.         }
  139.         parent::_putstream($s);
  140.     }
  141.     function _textstring($s)
  142.     {
  143.         if ($this->encrypted) {
  144.             $s = RC4($this->_objectkey($this->n), $s);
  145.         }
  146.         return parent::_textstring($s);
  147.     }
  148.     function _objectkey($n)
  149.     {
  150.         return substr($this->_md5_16($this->encryption_key.pack('VXxx',$n)),0,10);
  151.     }
  152.     function _putresources()
  153.     {
  154.         parent::_putresources();
  155.         if ($this->encrypted) {
  156.             $this->_newobj();
  157.             $this->enc_obj_id = $this->n;
  158.             $this->_out('<<');
  159.             $this->_putencryption();
  160.             $this->_out('>>');
  161.             $this->_out('endobj');
  162.         }
  163.     }
  164.     function _putencryption()
  165.     {
  166.         $this->_out('/Filter /Standard');
  167.         $this->_out('/V 1');
  168.         $this->_out('/R 2');
  169.         $this->_out('/O ('.$this->_escape($this->Ovalue).')');
  170.         $this->_out('/U ('.$this->_escape($this->Uvalue).')');
  171.         $this->_out('/P '.$this->Pvalue);
  172.     }
  173.     function _puttrailer()
  174.     {
  175.         parent::_puttrailer();
  176.         if ($this->encrypted) {
  177.             $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
  178.             $this->_out('/ID [()()]');
  179.         }
  180.     }
  181.     function _md5_16($string)
  182.     {
  183.         return pack('H*',md5($string));
  184.     }
  185.     function _Ovalue($user_pass, $owner_pass)
  186.     {
  187.         $tmp = $this->_md5_16($owner_pass);
  188.         $owner_RC4_key = substr($tmp,0,5);
  189.         return RC4($owner_RC4_key, $user_pass);
  190.     }
  191.     function _Uvalue()
  192.     {
  193.         return RC4($this->encryption_key, $this->padding);
  194.     }
  195.    function _generateencryptionkey($user_pass, $owner_pass, $protection)
  196.     {
  197.         $user_pass = substr($user_pass.$this->padding,0,32);
  198.         $owner_pass = substr($owner_pass.$this->padding,0,32);
  199.         $this->Ovalue = $this->_Ovalue($user_pass,$owner_pass);
  200.         $tmp = $this->_md5_16($user_pass.$this->Ovalue.chr($protection)."\xFF\xFF\xFF");
  201.         $this->encryption_key = substr($tmp,0,5);
  202.         $this->Uvalue = $this->_Uvalue();
  203.         $this->Pvalue = -(($protection^255)+1);
  204.     }
  205. }
  206. //-- create new object from FPDF_Protection class
  207. $pdf = new FPDF_Protection();
  208. $pdf->AddPage();
  209. $pdf->SetLineWidth(1.5);
  210. $pdf->SetFillColor(255,0,0);
  211. $pdf->Rect(10,10,40,40,'DF');
  212. $pdf->SetAlpha(0.5);
  213. $pdf->SetFillColor(0,255,0);
  214. $pdf->Rect(20,20,40,40,'DF');
  215. $pdf->Image('lena.jpg',30,30,40);
  216. $pdf->SetAlpha(1);
  217. $pdf->SetFont('Arial', '', 12);
  218. $pdf->Text(46,68,'Lena');
  219. $pdf->SetProtection(array('print'));
  220. $pdf->AddPage();
  221. $pdf->SetFont('Arial');
  222. $pdf->Write(10,'You can print me but not copy my text.');
  223. $pdf->Output();
  224. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement