PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/fuel/core/classes/crypt.php

https://github.com/mentariworks/feedmalaya-draft
PHP | 191 lines | 101 code | 32 blank | 58 comment | 10 complexity | dc5e5e077508b33e6e6dec4b63c0d931 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /**
  3. * Fuel is a fast, lightweight, community driven PHP5 framework.
  4. *
  5. * @package Fuel
  6. * @version 1.0
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2011 Fuel Development Team
  10. * @link http://fuelphp.com
  11. */
  12. namespace Fuel\Core;
  13. import('phpseclib/Crypt/AES', 'vendor');
  14. import('phpseclib/Crypt/Hash', 'vendor');
  15. use \PHPSecLib\Crypt_AES;
  16. use \PHPSecLib\Crypt_Hash;
  17. class Crypt {
  18. /*
  19. * Crypto object used to encrypt/decrypt
  20. *
  21. * @var object
  22. */
  23. private static $crypter = null;
  24. /*
  25. * Hash object used to generate hashes
  26. *
  27. * @var object
  28. */
  29. private static $hasher = null;
  30. /*
  31. * Crypto configuration
  32. *
  33. * @var array
  34. */
  35. private static $config = array();
  36. /*
  37. * initialisation and auto configuration
  38. */
  39. public static function _init()
  40. {
  41. static::$crypter = new Crypt_AES();
  42. static::$hasher = new Crypt_Hash('sha256');
  43. // load the config
  44. \Config::load('crypt', true);
  45. static::$config = \Config::get('crypt', array ());
  46. // generate random crypto keys if we don't have them or they are incorrect length
  47. $update = false;
  48. foreach(array('crypto_key', 'crypto_iv', 'crypto_hmac') as $key)
  49. {
  50. if ( empty(static::$config[$key]) || (strlen(static::$config[$key]) % 4) != 0)
  51. {
  52. $crypto = '';
  53. for ($i = 0; $i < 8; $i++) {
  54. $crypto .= static::safe_b64encode(pack('n', mt_rand(0, 0xFFFF)));
  55. }
  56. static::$config[$key] = $crypto;
  57. $update = true;
  58. }
  59. }
  60. // update the config if needed
  61. if ($update === true)
  62. {
  63. try
  64. {
  65. \Config::save('crypt', static::$config);
  66. }
  67. catch (\File_Exception $e)
  68. {
  69. throw new \Exception('Crypt keys are invalid or missing, and app/config/crypt.php could not be written.');
  70. }
  71. }
  72. static::$crypter->enableContinuousBuffer();
  73. static::$hasher->setKey(static::safe_b64decode(static::$config['crypto_hmac']));
  74. }
  75. // --------------------------------------------------------------------
  76. /*
  77. * encrypt a string value, optionally with a custom key
  78. *
  79. * @param string value to encrypt
  80. * @param string optional custom key to be used for this encryption
  81. * @access public
  82. * @return string encrypted value
  83. */
  84. public static function encode($value, $key = false)
  85. {
  86. $key ? static::$crypter->setKey($key) : static::$crypter->setKey(static::safe_b64decode(static::$config['crypto_key']));
  87. static::$crypter->setIV(static::safe_b64decode(static::$config['crypto_iv']));
  88. $value = static::$crypter->encrypt($value);
  89. return static::safe_b64encode(static::add_hmac($value));
  90. }
  91. // --------------------------------------------------------------------
  92. /*
  93. * decrypt a string value, optionally with a custom key
  94. *
  95. * @param string value to decrypt
  96. * @param string optional custom key to be used for this encryption
  97. * @access public
  98. * @return string encrypted value
  99. */
  100. public static function decode($value, $key = false)
  101. {
  102. $key ? static::$crypter->setKey($key) : static::$crypter->setKey(static::safe_b64decode(static::$config['crypto_key']));
  103. static::$crypter->setIV(static::safe_b64decode(static::$config['crypto_iv']));
  104. $value = static::safe_b64decode($value);
  105. if ($value = static::validate_hmac($value))
  106. {
  107. return static::$crypter->decrypt($value);
  108. }
  109. else
  110. {
  111. return false;
  112. }
  113. }
  114. // --------------------------------------------------------------------
  115. private static function safe_b64encode($value)
  116. {
  117. $data = base64_encode($value);
  118. $data = str_replace(array('+','/','='),array('-','_',''),$data);
  119. return $data;
  120. }
  121. private static function safe_b64decode($value)
  122. {
  123. $data = str_replace(array('-','_'),array('+','/'),$value);
  124. $mod4 = strlen($data) % 4;
  125. if ($mod4) {
  126. $data .= substr('====', $mod4);
  127. }
  128. return base64_decode($data);
  129. }
  130. private static function add_hmac($value)
  131. {
  132. // calculate the hmac-sha256 hash of this value
  133. $hmac = static::safe_b64encode(static::$hasher->hash($value));
  134. // append it and return the hmac protected string
  135. return $value.$hmac;
  136. }
  137. private static function validate_hmac($value)
  138. {
  139. // strip the hmac-sha256 hash from the value
  140. $hmac = substr($value, strlen($value)-43);
  141. // and remove it from the value
  142. $value = substr($value, 0, strlen($value)-43);
  143. // only return the value if it wasn't tampered with
  144. return (static::secure_compare(static::safe_b64encode(static::$hasher->hash($value)), $hmac)) ? $value : false;
  145. }
  146. private static function secure_compare($a, $b) {
  147. // make sure we're only comparing equal length strings
  148. if (strlen($a) !== strlen($b)) {
  149. return false;
  150. }
  151. // and that all comparisons take equal time
  152. $result = 0;
  153. for ($i = 0; $i < strlen($a); $i++) {
  154. $result |= ord($a[$i]) ^ ord($b[$i]);
  155. }
  156. return $result == 0;
  157. }
  158. }
  159. /* End of file crypt.php */