This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Encryptor.php

By: a guest on Jan 28th, 2014  |  syntax: PHP  |  size: 5.76 KB  |  views: 23  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?php namespace Illuminate\Encryption;
  2.  
  3. class DecryptException extends \RuntimeException {}
  4.  
  5. class Encrypter {
  6.  
  7.         /**
  8.          * The encryption key.
  9.          *
  10.          * @var string
  11.          */
  12.         protected $key;
  13.  
  14.         /**
  15.          * The algorithm used for encryption.
  16.          *
  17.          * @var string
  18.          */
  19.         protected $cipher = 'rijndael-256';
  20.  
  21.         /**
  22.          * The mode used for encryption.
  23.          *
  24.          * @var string
  25.          */
  26.         protected $mode = 'cbc';
  27.  
  28.         /**
  29.          * The block size of the cipher.
  30.          *
  31.          * @var int
  32.          */
  33.         protected $block = 32;
  34.  
  35.         /**
  36.          * Create a new encrypter instance.
  37.          *
  38.          * @param  string  $key
  39.          * @return void
  40.          */
  41.         public function __construct($key)
  42.         {
  43.                 $this->key = $key;
  44.         }
  45.  
  46.         /**
  47.          * Encrypt the given value.
  48.          *
  49.          * @param  string  $value
  50.          * @return string
  51.          */
  52.         public function encrypt($value)
  53.         {
  54.                 $iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
  55.  
  56.                 $value = base64_encode($this->padAndMcrypt($value, $iv));
  57.  
  58.                 // Once we have the encrypted value we will go ahead base64_encode the input
  59.                 // vector and create the MAC for the encrypted value so we can verify its
  60.                 // authenticity. Then, we'll JSON encode the data in a "payload" array.
  61.                 $mac = $this->hash($iv = base64_encode($iv), $value);
  62.  
  63.                 return base64_encode(json_encode(compact('iv', 'value', 'mac')));
  64.         }
  65.  
  66.         /**
  67.          * Pad and use mcrypt on the given value and input vector.
  68.          *
  69.          * @param  string  $value
  70.          * @param  string  $iv
  71.          * @return string
  72.          */
  73.         protected function padAndMcrypt($value, $iv)
  74.         {
  75.                 $value = $this->addPadding(serialize($value));
  76.  
  77.                 return mcrypt_encrypt($this->cipher, $this->key, $value, $this->mode, $iv);
  78.         }
  79.  
  80.         /**
  81.          * Decrypt the given value.
  82.          *
  83.          * @param  string  $payload
  84.          * @return string
  85.          */
  86.         public function decrypt($payload)
  87.         {
  88.                 $payload = $this->getJsonPayload($payload);
  89.  
  90.                 // We'll go ahead and remove the PKCS7 padding from the encrypted value before
  91.                 // we decrypt it. Once we have the de-padded value, we will grab the vector
  92.                 // and decrypt the data, passing back the unserialized from of the value.
  93.                 $value = base64_decode($payload['value']);
  94.  
  95.                 $iv = base64_decode($payload['iv']);
  96.  
  97.                 return unserialize($this->stripPadding($this->mcryptDecrypt($value, $iv)));
  98.         }
  99.  
  100.         /**
  101.          * Run the mcrypt decryption routine for the value.
  102.          *
  103.          * @param  string  $value
  104.          * @param  string  $iv
  105.          * @return string
  106.          */
  107.         protected function mcryptDecrypt($value, $iv)
  108.         {
  109.                 return mcrypt_decrypt($this->cipher, $this->key, $value, $this->mode, $iv);
  110.         }
  111.  
  112.         /**
  113.          * Get the JSON array from the given payload.
  114.          *
  115.          * @param  string  $payload
  116.          * @return array
  117.          *
  118.          * @throws DecryptException
  119.          */
  120.         protected function getJsonPayload($payload)
  121.         {
  122.                 $payload = json_decode(base64_decode($payload), true);
  123.  
  124.                 // If the payload is not valid JSON or does not have the proper keys set we will
  125.                 // assume it is invalid and bail out of the routine since we will not be able
  126.                 // to decrypt the given value. We'll also check the MAC for this encryption.
  127.                 if ( ! $payload || $this->invalidPayload($payload))
  128.                 {
  129.                         throw new DecryptException("Invalid data.");
  130.                 }
  131.  
  132.                 if ( ! $this->validMac($payload))
  133.                 {
  134.                         throw new DecryptException("MAC is invalid.");
  135.                 }
  136.  
  137.                 return $payload;
  138.         }
  139.  
  140.         /**
  141.          * Determine if the MAC for the given payload is valid.
  142.          *
  143.          * @param  array  $payload
  144.          * @return bool
  145.          */
  146.         protected function validMac(array $payload)
  147.         {
  148.                 return ($payload['mac'] === $this->hash($payload['iv'], $payload['value']));
  149.         }
  150.  
  151.         /**
  152.          * Create a MAC for the given value.
  153.          *
  154.          * @param  string  $iv
  155.          * @param  string  $value
  156.          * @return string
  157.          */
  158.         protected function hash($iv, $value)
  159.         {
  160.                 return hash_hmac('sha256', $iv.$value, $this->key);
  161.         }
  162.  
  163.         /**
  164.          * Add PKCS7 padding to a given value.
  165.          *
  166.          * @param  string  $value
  167.          * @return string
  168.          */
  169.         protected function addPadding($value)
  170.         {
  171.                 $pad = $this->block - (strlen($value) % $this->block);
  172.  
  173.                 return $value.str_repeat(chr($pad), $pad);
  174.         }
  175.  
  176.         /**
  177.          * Remove the padding from the given value.
  178.          *
  179.          * @param  string  $value
  180.          * @return string
  181.          */
  182.         protected function stripPadding($value)
  183.         {
  184.                 $pad = ord($value[($len = strlen($value)) - 1]);
  185.  
  186.                 return $this->paddingIsValid($pad, $value) ? substr($value, 0, strlen($value) - $pad) : $value;
  187.         }
  188.  
  189.         /**
  190.          * Determine if the given padding for a value is valid.
  191.          *
  192.          * @param  string  $pad
  193.          * @param  string  $value
  194.          * @return bool
  195.          */
  196.         protected function paddingIsValid($pad, $value)
  197.         {
  198.                 $beforePad = strlen($value) - $pad;
  199.  
  200.                 return substr($value, $beforePad) == str_repeat(substr($value, -1), $pad);
  201.         }
  202.  
  203.         /**
  204.          * Verify that the encryption payload is valid.
  205.          *
  206.          * @param  array|mixed  $data
  207.          * @return bool
  208.          */
  209.         protected function invalidPayload($data)
  210.         {
  211.                 return ! is_array($data) || ! isset($data['iv']) || ! isset($data['value']) || ! isset($data['mac']);
  212.         }
  213.  
  214.         /**
  215.          * Get the IV size for the cipher.
  216.          *
  217.          * @return int
  218.          */
  219.         protected function getIvSize()
  220.         {
  221.                 return mcrypt_get_iv_size($this->cipher, $this->mode);
  222.         }
  223.  
  224.         /**
  225.          * Get the random data source available for the OS.
  226.          *
  227.          * @return int
  228.          */
  229.         protected function getRandomizer()
  230.         {
  231.                 if (defined('MCRYPT_DEV_URANDOM')) return MCRYPT_DEV_URANDOM;
  232.  
  233.                 if (defined('MCRYPT_DEV_RANDOM')) return MCRYPT_DEV_RANDOM;
  234.  
  235.                 mt_srand();
  236.  
  237.                 return MCRYPT_RAND;
  238.         }
  239.  
  240.         /**
  241.          * Set the encryption key.
  242.          *
  243.          * @param  string  $key
  244.          * @return void
  245.          */
  246.         public function setKey($key)
  247.         {
  248.                 $this->key = $key;
  249.         }
  250.  
  251.         /**
  252.          * Set the encryption cipher.
  253.          *
  254.          * @param  string  $cipher
  255.          * @return void
  256.          */
  257.         public function setCipher($cipher)
  258.         {
  259.                 $this->cipher = $cipher;
  260.         }
  261.  
  262.         /**
  263.          * Set the encryption mode.
  264.          *
  265.          * @param  string  $mode
  266.          * @return void
  267.          */
  268.         public function setMode($mode)
  269.         {
  270.                 $this->mode = $mode;
  271.         }
  272.  
  273. }
clone this paste RAW Paste Data