Secury.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <?php
  2. namespace ForkBB\Core;
  3. use RuntimeException;
  4. use UnexpectedValueException;
  5. use InvalidArgumentException;
  6. class Secury
  7. {
  8. /**
  9. * Algorithm and salt for hash_hmac
  10. * @var array
  11. */
  12. protected $hmac;
  13. /**
  14. * Конструктор
  15. *
  16. * @param array $hmac
  17. *
  18. * @throws InvalidArgumentException
  19. * @throws UnexpectedValueException
  20. */
  21. public function __construct(array $hmac)
  22. {
  23. if (empty($hmac['salt']) || empty($hmac['algo'])) {
  24. throw new InvalidArgumentException('Algorithm and salt can not be empty');
  25. }
  26. if (! \in_array($hmac['algo'], \hash_algos())) {
  27. throw new UnexpectedValueException('Algorithm not supported');
  28. }
  29. $this->hmac = $hmac;
  30. }
  31. /**
  32. * Обертка для hash_hmac
  33. *
  34. * @param string $data
  35. *
  36. * @return string
  37. */
  38. public function hash($data)
  39. {
  40. return $this->hmac($data, \md5(__DIR__));
  41. }
  42. /**
  43. * Обертка для hash_hmac
  44. *
  45. * @param string $data
  46. * @param string $key
  47. *
  48. * @throws InvalidArgumentException
  49. *
  50. * @return string
  51. */
  52. public function hmac($data, $key)
  53. {
  54. if (empty($key)) {
  55. throw new InvalidArgumentException('Key can not be empty');
  56. }
  57. return \hash_hmac($this->hmac['algo'], $data, $key . $this->hmac['salt']);
  58. }
  59. /**
  60. * Возвращает случайный набор байтов заданной длины
  61. *
  62. * @param int $len
  63. *
  64. * @throws RuntimeException
  65. *
  66. * @return string
  67. */
  68. public function randomKey($len)
  69. {
  70. $key = '';
  71. if (\function_exists('\\random_bytes')) {
  72. $key .= (string) \random_bytes($len);
  73. }
  74. if (\strlen($key) < $len && \function_exists('\\mcrypt_create_iv')) {
  75. $key .= (string) \mcrypt_create_iv($len, \MCRYPT_DEV_URANDOM);
  76. }
  77. if (\strlen($key) < $len && \function_exists('\\openssl_random_pseudo_bytes')) {
  78. $tmp = (string) \openssl_random_pseudo_bytes($len, $strong);
  79. if ($strong) {
  80. $key .= $tmp;
  81. }
  82. }
  83. if (\strlen($key) < $len) {
  84. throw new RuntimeException('Could not gather sufficient random data');
  85. }
  86. return $key;
  87. }
  88. /**
  89. * Возвращает случайную строку заданной длины состоящую из символов 0-9 и a-f
  90. *
  91. * @param int $len
  92. *
  93. * @return string
  94. */
  95. public function randomHash($len)
  96. {
  97. return \substr(\bin2hex($this->randomKey($len)), 0, $len);
  98. }
  99. /**
  100. * Возвращает случайную строку заданной длины состоящую из цифр, латиницы,
  101. * знака минус и символа подчеркивания
  102. *
  103. * @param int $len
  104. *
  105. * @return string
  106. */
  107. public function randomPass($len)
  108. {
  109. $key = $this->randomKey($len);
  110. $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
  111. $result = '';
  112. for ($i = 0; $i < $len; ++$i) {
  113. $result .= $chars[\ord($key[$i]) % 64];
  114. }
  115. return $result;
  116. }
  117. /**
  118. * Replacing invalid UTF-8 characters and remove control characters
  119. *
  120. * @param mixed $data
  121. *
  122. * @return mixed
  123. */
  124. public function replInvalidChars($data)
  125. {
  126. if (\is_array($data)) {
  127. return \array_map([$this, 'replInvalidChars'], $data);
  128. } elseif (\is_int($data)) {
  129. return (int) $data;
  130. }
  131. // Replacing invalid UTF-8 characters
  132. // slow, small memory
  133. //$data = mb_convert_encoding((string) $data, 'UTF-8', 'UTF-8');
  134. // fast, large memory
  135. $data = \htmlspecialchars_decode(\htmlspecialchars((string) $data, \ENT_SUBSTITUTE, 'UTF-8'));
  136. // Remove control characters
  137. return \preg_replace('%[\x00-\x08\x0B-\x0C\x0E-\x1F]%', '', $data);
  138. }
  139. }