gluon-web-remote

Web remote Administration for big size of gluon routers
git clone git://archive.git.mtrnord.blog/MTRNord/gluon-web-remote.git
Log | Files | Refs | README

Encryption.php (4324B)


      1 <?php
      2 
      3 /**
      4  * Encryption and Decryption Class
      5  *
      6  */
      7 
      8 class Encryption{
      9 
     10     /**
     11      * Cipher algorithm
     12      *
     13      * @var string
     14      */
     15     const CIPHER = 'aes-256-cbc';
     16 
     17     /**
     18      * Hash function
     19      *
     20      * @var string
     21      */
     22     const HASH_FUNCTION = 'sha256';
     23 
     24     /**
     25      * constructor for Encryption object.
     26      *
     27      * @access private
     28      */
     29     private function __construct(){}
     30 
     31     /**
     32      * Encrypt a string.
     33      *
     34      * @access public
     35      * @static static method
     36      * @param  string	$plain
     37      * @return string
     38      * @throws Exception If functions don't exists
     39      */
     40     public static function encrypt($plain){
     41 
     42         if(!function_exists('openssl_cipher_iv_length') ||
     43             !function_exists('openssl_random_pseudo_bytes') ||
     44             !function_exists('openssl_encrypt')){
     45             throw new Exception("Encryption function don't exists");
     46         }
     47 
     48         // generate initialization vector,
     49         // this will make $iv different every time,
     50         // so, encrypted string will be also different.
     51         $iv_size = openssl_cipher_iv_length(self::CIPHER);
     52         $iv      = openssl_random_pseudo_bytes($iv_size);
     53 
     54         // generate key for authentication using ENCRYPTION_KEY & HMAC_SALT
     55         $key = mb_substr(hash(self::HASH_FUNCTION, Config::get('ENCRYPTION_KEY') . Config::get('HMAC_SALT')), 0, 32, '8bit');
     56 
     57         // append initialization vector
     58         $encrypted_string = openssl_encrypt($plain, self::CIPHER, $key, OPENSSL_RAW_DATA, $iv);
     59         $ciphertext       = $iv . $encrypted_string;
     60 
     61         // apply the HMAC
     62         $hmac = hash_hmac('sha256', $ciphertext, $key);
     63 
     64         return $hmac . $ciphertext;
     65     }
     66 
     67     /**
     68      * Decrypted a string.
     69      *
     70      * @access public
     71      * @static static method
     72      * @param  string $ciphertext
     73      * @return string
     74      * @throws Exception If $ciphertext is empty, or If functions don't exists
     75      */
     76     public static function decrypt($ciphertext){
     77 
     78         if(empty($ciphertext)){
     79             throw new Exception("the string to decrypt can't be empty");
     80         }
     81 
     82         if(!function_exists('openssl_cipher_iv_length') ||
     83             !function_exists('openssl_decrypt')){
     84             throw new Exception("Encryption function don't exists");
     85         }
     86 
     87         // generate key used for authentication using ENCRYPTION_KEY & HMAC_SALT
     88         $key = mb_substr(hash(self::HASH_FUNCTION, Config::get('ENCRYPTION_KEY') . Config::get('HMAC_SALT')), 0, 32, '8bit');
     89 
     90         // split cipher into: hmac, cipher & iv
     91         $macSize    = 64;
     92         $hmac 	    = mb_substr($ciphertext, 0, $macSize, '8bit');
     93         $iv_cipher  = mb_substr($ciphertext, $macSize, null, '8bit');
     94 
     95         // generate original hmac & compare it with the one in $ciphertext
     96         $originalHmac = hash_hmac('sha256', $iv_cipher, $key);
     97         if(!self::hashEquals($hmac, $originalHmac)){
     98             return false;
     99         }
    100 
    101         // split out the initialization vector and cipher
    102         $iv_size = openssl_cipher_iv_length(self::CIPHER);
    103         $iv      = mb_substr($iv_cipher, 0, $iv_size, '8bit');
    104         $cipher  = mb_substr($iv_cipher, $iv_size, null, '8bit');
    105 
    106         return openssl_decrypt($cipher, self::CIPHER, $key, OPENSSL_RAW_DATA, $iv);
    107     }
    108 
    109     /**
    110      * A timing attack resistant comparison.
    111      *
    112      * @access private
    113      * @static static method
    114      * @param string $hmac The hmac from the ciphertext being decrypted.
    115      * @param string $compare The comparison hmac.
    116      * @return bool
    117      * @see https://github.com/sarciszewski/php-future/blob/bd6c91fb924b2b35a3e4f4074a642868bd051baf/src/Security.php#L36
    118      */
    119     private static function hashEquals($hmac, $compare){
    120 
    121         if (function_exists('hash_equals')) {
    122             return hash_equals($hmac, $compare);
    123         }
    124 
    125         // if hash_equals() is not available,
    126         // then use the following snippet.
    127         // It's equivalent to hash_equals() in PHP 5.6.
    128         $hashLength    = mb_strlen($hmac, '8bit');
    129         $compareLength = mb_strlen($compare, '8bit');
    130 
    131         if ($hashLength !== $compareLength) {
    132             return false;
    133         }
    134 
    135         $result = 0;
    136         for ($i = 0; $i < $hashLength; $i++) {
    137             $result |= (ord($hmac[$i]) ^ ord($compare[$i]));
    138         }
    139 
    140         return $result === 0;
    141     }
    142 }