PageRenderTime 58ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/fuel/core/classes/crypt.php

https://github.com/jsidhu/assets
PHP | 196 lines | 105 code | 33 blank | 58 comment | 10 complexity | 9148916d95c39fe10023c78273f699f2 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /**
  3. * Part of the Fuel 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. /*
  20. * Crypto object used to encrypt/decrypt
  21. *
  22. * @var object
  23. */
  24. private static $crypter = null;
  25. /*
  26. * Hash object used to generate hashes
  27. *
  28. * @var object
  29. */
  30. private static $hasher = null;
  31. /*
  32. * Crypto configuration
  33. *
  34. * @var array
  35. */
  36. private static $config = array();
  37. /*
  38. * initialisation and auto configuration
  39. */
  40. public static function _init()
  41. {
  42. static::$crypter = new Crypt_AES();
  43. static::$hasher = new Crypt_Hash('sha256');
  44. // load the config
  45. \Config::load('crypt', true);
  46. static::$config = \Config::get('crypt', array ());
  47. // generate random crypto keys if we don't have them or they are incorrect length
  48. $update = false;
  49. foreach(array('crypto_key', 'crypto_iv', 'crypto_hmac') as $key)
  50. {
  51. if ( empty(static::$config[$key]) || (strlen(static::$config[$key]) % 4) != 0)
  52. {
  53. $crypto = '';
  54. for ($i = 0; $i < 8; $i++) {
  55. $crypto .= static::safe_b64encode(pack('n', mt_rand(0, 0xFFFF)));
  56. }
  57. static::$config[$key] = $crypto;
  58. $update = true;
  59. }
  60. }
  61. // update the config if needed
  62. if ($update === true)
  63. {
  64. try
  65. {
  66. \Config::save('crypt', static::$config);
  67. }
  68. catch (\FileAccessException $e)
  69. {
  70. // failed to write the config file, inform the user
  71. echo \View::forge('errors/crypt_keys', array(
  72. 'keys' => static::$config
  73. ));
  74. die();
  75. }
  76. }
  77. static::$crypter->enableContinuousBuffer();
  78. static::$hasher->setKey(static::safe_b64decode(static::$config['crypto_hmac']));
  79. }
  80. // --------------------------------------------------------------------
  81. /*
  82. * encrypt a string value, optionally with a custom key
  83. *
  84. * @param string value to encrypt
  85. * @param string optional custom key to be used for this encryption
  86. * @access public
  87. * @return string encrypted value
  88. */
  89. public static function encode($value, $key = false)
  90. {
  91. $key ? static::$crypter->setKey($key) : static::$crypter->setKey(static::safe_b64decode(static::$config['crypto_key']));
  92. static::$crypter->setIV(static::safe_b64decode(static::$config['crypto_iv']));
  93. $value = static::$crypter->encrypt($value);
  94. return static::safe_b64encode(static::add_hmac($value));
  95. }
  96. // --------------------------------------------------------------------
  97. /*
  98. * decrypt a string value, optionally with a custom key
  99. *
  100. * @param string value to decrypt
  101. * @param string optional custom key to be used for this encryption
  102. * @access public
  103. * @return string encrypted value
  104. */
  105. public static function decode($value, $key = false)
  106. {
  107. $key ? static::$crypter->setKey($key) : static::$crypter->setKey(static::safe_b64decode(static::$config['crypto_key']));
  108. static::$crypter->setIV(static::safe_b64decode(static::$config['crypto_iv']));
  109. $value = static::safe_b64decode($value);
  110. if ($value = static::validate_hmac($value))
  111. {
  112. return static::$crypter->decrypt($value);
  113. }
  114. else
  115. {
  116. return false;
  117. }
  118. }
  119. // --------------------------------------------------------------------
  120. private static function safe_b64encode($value)
  121. {
  122. $data = base64_encode($value);
  123. $data = str_replace(array('+','/','='),array('-','_',''),$data);
  124. return $data;
  125. }
  126. private static function safe_b64decode($value)
  127. {
  128. $data = str_replace(array('-','_'),array('+','/'),$value);
  129. $mod4 = strlen($data) % 4;
  130. if ($mod4) {
  131. $data .= substr('====', $mod4);
  132. }
  133. return base64_decode($data);
  134. }
  135. private static function add_hmac($value)
  136. {
  137. // calculate the hmac-sha256 hash of this value
  138. $hmac = static::safe_b64encode(static::$hasher->hash($value));
  139. // append it and return the hmac protected string
  140. return $value.$hmac;
  141. }
  142. private static function validate_hmac($value)
  143. {
  144. // strip the hmac-sha256 hash from the value
  145. $hmac = substr($value, strlen($value)-43);
  146. // and remove it from the value
  147. $value = substr($value, 0, strlen($value)-43);
  148. // only return the value if it wasn't tampered with
  149. return (static::secure_compare(static::safe_b64encode(static::$hasher->hash($value)), $hmac)) ? $value : false;
  150. }
  151. private static function secure_compare($a, $b) {
  152. // make sure we're only comparing equal length strings
  153. if (strlen($a) !== strlen($b)) {
  154. return false;
  155. }
  156. // and that all comparisons take equal time
  157. $result = 0;
  158. for ($i = 0; $i < strlen($a); $i++) {
  159. $result |= ord($a[$i]) ^ ord($b[$i]);
  160. }
  161. return $result == 0;
  162. }
  163. }