PageRenderTime 27ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/s2member/src/includes/classes/utils-encryption.inc.php

https://gitlab.com/pankajmohale/chef2go
PHP | 231 lines | 122 code | 22 blank | 87 comment | 37 complexity | d957cbfa69994877b75e22e9fb83a547 MD5 | raw file
  1. <?php
  2. // @codingStandardsIgnoreFile
  3. /**
  4. * Encryption utilities.
  5. *
  6. * @since 3.5 Nearly the first release.
  7. */
  8. if (!defined('WPINC')) { // MUST have.
  9. exit('Do not access this file directly.');
  10. }
  11. if (!class_exists('c_ws_plugin__s2member_utils_encryption')) {
  12. /**
  13. * Encryption utilities.
  14. *
  15. * @since 3.5 Nearly the first release.
  16. */
  17. class c_ws_plugin__s2member_utils_encryption
  18. {
  19. /**
  20. * Encryption key.
  21. *
  22. * @since 111106 Get key.
  23. *
  24. * @param string $key Custom key.
  25. *
  26. * @return string Encryption key.
  27. */
  28. public static function key($key = '')
  29. {
  30. if (($key = trim((string) $key))) {
  31. return $key;
  32. } elseif (($key = $GLOBALS['WS_PLUGIN__']['s2member']['o']['sec_encryption_key'])) {
  33. return $key;
  34. } elseif (($key = wp_salt())) {
  35. return $key;
  36. }
  37. return $key = md5($_SERVER['HTTP_HOST']);
  38. }
  39. /**
  40. * A unique, unguessable, non-numeric, caSe-insensitive key (20 chars max).
  41. *
  42. * @since 150124 Adding gift code generation.
  43. *
  44. * @note 32-bit systems usually have `PHP_INT_MAX` = `2147483647`.
  45. * We limit `mt_rand()` to a max of `999999999`.
  46. *
  47. * @note A max possible length of 20 chars assumes this function
  48. * will not be called after `Sat, 20 Nov 2286 17:46:39 GMT`.
  49. * At which point a UNIX timestamp will grow in size.
  50. *
  51. * @note Key always begins with a `k` to prevent PHP's `is_numeric()`
  52. * function from ever thinking it's a number in a different representation.
  53. * See: <http://php.net/manual/en/function.is-numeric.php> for further details.
  54. *
  55. * @return string A unique, unguessable, non-numeric, caSe-insensitive key (20 chars max).
  56. */
  57. public static function uunnci_key_20_max()
  58. {
  59. $microtime_19_max = number_format(microtime(true), 9, '.', '');
  60. // e.g., `9999999999`.`999999999` (max decimals: `9`, max overall precision: `19`).
  61. // Assuming timestamp is never > 10 digits; i.e., before `Sat, 20 Nov 2286 17:46:39 GMT`.
  62. list($seconds_10_max, $microseconds_9_max) = explode('.', $microtime_19_max, 2);
  63. // e.g., `array(`9999999999`, `999999999`)`. Max total digits combined: `19`.
  64. $seconds_base36 = base_convert($seconds_10_max, '10', '36'); // e.g., max `9999999999`, to base 36.
  65. $microseconds_base36 = base_convert($microseconds_9_max, '10', '36'); // e.g., max `999999999`, to base 36.
  66. $mt_rand_base36 = base_convert(mt_rand(1, 999999999), '10', '36'); // e.g., max `999999999`, to base 36.
  67. $key = 'k'.$mt_rand_base36.$seconds_base36.$microseconds_base36; // e.g., `kgjdgxr4ldqpdrgjdgxr`.
  68. return $key; // Max possible value: `kgjdgxr4ldqpdrgjdgxr` (20 chars).
  69. }
  70. /**
  71. * Encrypt w/ best possible technique.
  72. *
  73. * @since 3.5 Nearly the first release.
  74. *
  75. * @param string $string String to encrypt.
  76. * @param string $key Optional custom encryption key.
  77. * @param bool $w_md5_cs Defaults to true. When true, an MD5 checksum.
  78. * @param bool|null $allow_defuse Allow Defuse encryption as a better alternative?
  79. *
  80. * @return string Encrypted string.
  81. */
  82. public static function encrypt($string = '', $key = '', $w_md5_cs = true, $allow_defuse = null)
  83. {
  84. $allow_defuse = isset($allow_defuse) ? $allow_defuse
  85. : apply_filters('c_ws_plugin__s2member_allow_defuse', true);
  86. if ($allow_defuse && version_compare(PHP_VERSION, '7.0.4', '>=')) {
  87. return c_ws_plugin__s2member_utils_defuse::encrypt($string, $key);
  88. } // This is a new/improved way of handling encryption.
  89. if (function_exists('mcrypt_encrypt')
  90. && in_array('rijndael-256', @mcrypt_list_algorithms())
  91. && in_array('cbc', @mcrypt_list_modes())) {
  92. //
  93. $string = is_string($string) ? $string : '';
  94. $string = isset($string[0]) ? '~r2|'.$string : '';
  95. $key = self::key($key); // Get encryption key.
  96. $key = substr($key, 0, @mcrypt_get_key_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC));
  97. $iv = c_ws_plugin__s2member_utils_strings::random_str_gen(@mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), false);
  98. if (isset($string[0]) && is_string($e = @mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $string, MCRYPT_MODE_CBC, $iv)) && isset($e[0])) {
  99. $e = '~r2:'.$iv.($w_md5_cs ? ':'.md5($e) : '').'|'.$e;
  100. }
  101. return isset($e) && is_string($e) && isset($e[0])
  102. ? ($base64 = c_ws_plugin__s2member_utils_strings::base64_url_safe_encode($e))
  103. : ''; // Default to empty string.
  104. }
  105. return self::xencrypt($string, $key, $w_md5_cs);
  106. }
  107. /**
  108. * Decrypt w/ best possible technique.
  109. *
  110. * @since 3.5 Nearly the first release.
  111. *
  112. * @param string $base64 String to decrypt (base64).
  113. * @param string $key Optional custom decryption key.
  114. * @param bool|null $allow_defuse Allow Defuse encryption as a better alternative?
  115. *
  116. * @return string Decrypted string, else empty string.
  117. */
  118. public static function decrypt($base64 = '', $key = '', $allow_defuse = null)
  119. {
  120. if (!is_string($base64) || !isset($base64[0])) {
  121. return ''; // Not possible.
  122. } // Fail when not a string or empty.
  123. $allow_defuse = isset($allow_defuse) ? $allow_defuse
  124. : apply_filters('c_ws_plugin__s2member_allow_defuse', true);
  125. if ($allow_defuse && version_compare(PHP_VERSION, '7.0.4', '>=')
  126. && ($_d = c_ws_plugin__s2member_utils_defuse::decrypt($base64, $key))) {
  127. return $string = $_d; // Defuse success.
  128. } // This is a new/improved way of handling decryption.
  129. if (function_exists('mcrypt_decrypt')
  130. && in_array('rijndael-256', @mcrypt_list_algorithms())
  131. && in_array('cbc', @mcrypt_list_modes())) {
  132. //
  133. $e = c_ws_plugin__s2member_utils_strings::base64_url_safe_decode($base64);
  134. if (preg_match('/^~r2\:([a-zA-Z0-9]+)(?:\:([a-zA-Z0-9]+))?\|(.*)$/s', $e, $iv_md5_e)) {
  135. $key = self::key($key); // Get encryption key.
  136. $key = substr($key, 0, @mcrypt_get_key_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC));
  137. if (isset($iv_md5_e[3][0]) && (empty($iv_md5_e[2]) || $iv_md5_e[2] === md5($iv_md5_e[3]))) {
  138. $d = @mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $iv_md5_e[3], MCRYPT_MODE_CBC, $iv_md5_e[1]);
  139. }
  140. if (!isset($d)) { // Failed above?
  141. return ''; // Empty string on failure.
  142. } elseif (!strlen($d = preg_replace('/^~r2\|/', '', $d, 1, $r2)) || !$r2) {
  143. return ''; // Empty string on failure.
  144. }
  145. return $string = rtrim($d, "\0\4");
  146. }
  147. }
  148. return self::xdecrypt($base64, $key);
  149. }
  150. /**
  151. * XOR two-way encryption/decryption, with a base64 wrapper.
  152. *
  153. * @since 3.5 Nearly the first release.
  154. *
  155. * @param string $string A string of data to encrypt.
  156. * @param string $key Optional. Key used for encryption. Defaults to the one configured for s2Member. Short of that, defaults to: ``wp_salt()``.
  157. * @param bool $w_md5_cs Optional. Defaults to true. When true, an MD5 checksum is used in the encrypted string *(recommended)*.
  158. *
  159. * @return string Encrypted string.
  160. */
  161. public static function xencrypt($string = '', $key = '', $w_md5_cs = true)
  162. {
  163. $string = is_string($string) ? $string : '';
  164. $string = isset($string[0]) ? '~xe|'.$string : '';
  165. $key = self::key($key); // Get encryption key.
  166. for ($i = 1, $e = ''; $i <= strlen($string); ++$i) {
  167. $char = substr($string, $i - 1, 1);
  168. $keychar = substr($key, ($i % strlen($key)) - 1, 1);
  169. $e .= chr(ord($char) + ord($keychar));
  170. }
  171. $e = isset($e[0]) ? '~xe'.($w_md5_cs ? ':'.md5($e) : '').'|'.$e : '';
  172. return $base64 = isset($e[0]) ? ($base64 = c_ws_plugin__s2member_utils_strings::base64_url_safe_encode($e)) : '';
  173. }
  174. /**
  175. * XOR decryption.
  176. *
  177. * @since 3.5 Nearly the first release.
  178. *
  179. * @param string $base64 String to decrypt (base64).
  180. * @param string $key Optional custom decryption key.
  181. *
  182. * @return string Decrypted string.
  183. */
  184. public static function xdecrypt($base64 = '', $key = '')
  185. {
  186. if (!is_string($base64) || !isset($base64[0])) {
  187. return ''; // Not possible.
  188. } // Fail when not a string or empty.
  189. $e = c_ws_plugin__s2member_utils_strings::base64_url_safe_decode($base64);
  190. if (preg_match('/^~xe(?:\:([a-zA-Z0-9]+))?\|(.*)$/s', $e, $md5_e)) {
  191. $key = self::key($key); // Get encryption key.
  192. if (isset($md5_e[2][0]) && (empty($md5_e[1]) || $md5_e[1] === md5($md5_e[2]))) {
  193. for ($i = 1, $d = ''; $i <= strlen($md5_e[2]); ++$i) {
  194. $char = substr($md5_e[2], $i - 1, 1);
  195. $keychar = substr($key, ($i % strlen($key)) - 1, 1);
  196. $d .= chr(ord($char) - ord($keychar));
  197. } // Reverse XOR encryption.
  198. } // Else the checksum was not a match.
  199. if (!isset($d)) { // Failed above?
  200. return ''; // Empty string on failure.
  201. } elseif (!strlen($d = preg_replace('/^~xe\|/', '', $d, 1, $xe)) || !$xe) {
  202. return ''; // Empty string on failure.
  203. }
  204. return $string = $d; // Decryption success.
  205. }
  206. return ''; // Empty string on failure.
  207. }
  208. }
  209. }