2017-01-11 15:31:43 +00:00
|
|
|
<?php
|
2020-12-21 10:40:19 +00:00
|
|
|
/**
|
|
|
|
* This file is part of the ForkBB <https://github.com/forkbb>.
|
|
|
|
*
|
|
|
|
* @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
|
|
|
|
* @license The MIT License (MIT)
|
|
|
|
*/
|
2017-01-11 15:31:43 +00:00
|
|
|
|
2020-10-14 13:01:43 +00:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
2017-01-11 15:31:43 +00:00
|
|
|
namespace ForkBB\Core;
|
|
|
|
|
2020-10-17 13:29:10 +00:00
|
|
|
use Normalizer;
|
2017-01-11 15:31:43 +00:00
|
|
|
use RuntimeException;
|
|
|
|
use UnexpectedValueException;
|
|
|
|
use InvalidArgumentException;
|
|
|
|
|
|
|
|
class Secury
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Algorithm and salt for hash_hmac
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $hmac;
|
|
|
|
|
|
|
|
public function __construct(array $hmac)
|
|
|
|
{
|
2020-06-28 05:10:59 +00:00
|
|
|
if (
|
|
|
|
empty($hmac['salt'])
|
|
|
|
|| empty($hmac['algo'])
|
|
|
|
) {
|
2017-01-11 15:31:43 +00:00
|
|
|
throw new InvalidArgumentException('Algorithm and salt can not be empty');
|
|
|
|
}
|
2020-05-26 06:02:31 +00:00
|
|
|
if (! \in_array($hmac['algo'], \hash_hmac_algos())) {
|
2017-01-11 15:31:43 +00:00
|
|
|
throw new UnexpectedValueException('Algorithm not supported');
|
|
|
|
}
|
|
|
|
$this->hmac = $hmac;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Обертка для hash_hmac
|
2017-02-20 14:52:45 +00:00
|
|
|
*/
|
2020-05-24 11:30:48 +00:00
|
|
|
public function hash(string $data): string
|
2017-02-20 14:52:45 +00:00
|
|
|
{
|
2018-03-08 12:39:54 +00:00
|
|
|
return $this->hmac($data, \md5(__DIR__));
|
2017-02-20 14:52:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Обертка для hash_hmac
|
2017-01-11 15:31:43 +00:00
|
|
|
*/
|
2020-05-24 11:30:48 +00:00
|
|
|
public function hmac(string $data, string $key): string
|
2017-01-11 15:31:43 +00:00
|
|
|
{
|
|
|
|
if (empty($key)) {
|
|
|
|
throw new InvalidArgumentException('Key can not be empty');
|
|
|
|
}
|
2020-07-03 08:28:10 +00:00
|
|
|
|
2018-03-08 12:39:54 +00:00
|
|
|
return \hash_hmac($this->hmac['algo'], $data, $key . $this->hmac['salt']);
|
2017-01-11 15:31:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает случайную строку заданной длины состоящую из символов 0-9 и a-f
|
|
|
|
*/
|
2020-05-24 11:30:48 +00:00
|
|
|
public function randomHash(int $len): string
|
2017-01-11 15:31:43 +00:00
|
|
|
{
|
2020-05-24 13:31:05 +00:00
|
|
|
return \substr(\bin2hex(\random_bytes($len)), 0, $len);
|
2017-01-11 15:31:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Возвращает случайную строку заданной длины состоящую из цифр, латиницы,
|
|
|
|
* знака минус и символа подчеркивания
|
|
|
|
*/
|
2020-05-24 11:30:48 +00:00
|
|
|
public function randomPass(int $len): string
|
2017-01-11 15:31:43 +00:00
|
|
|
{
|
2020-05-24 13:31:05 +00:00
|
|
|
$key = \random_bytes($len);
|
2017-01-11 15:31:43 +00:00
|
|
|
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
|
|
$result = '';
|
|
|
|
for ($i = 0; $i < $len; ++$i) {
|
2019-11-28 13:25:13 +00:00
|
|
|
$result .= $chars[\ord($key[$i]) % 64];
|
2017-01-11 15:31:43 +00:00
|
|
|
}
|
2020-07-03 08:28:10 +00:00
|
|
|
|
2017-01-11 15:31:43 +00:00
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Replacing invalid UTF-8 characters and remove control characters
|
|
|
|
*/
|
2020-09-12 16:22:32 +00:00
|
|
|
public function replInvalidChars(/* mixed */ $data) /* : mixed */
|
2017-01-11 15:31:43 +00:00
|
|
|
{
|
2018-03-08 12:39:54 +00:00
|
|
|
if (\is_array($data)) {
|
|
|
|
return \array_map([$this, 'replInvalidChars'], $data);
|
2018-04-01 02:51:59 +00:00
|
|
|
} elseif (\is_int($data)) {
|
2020-10-27 06:31:10 +00:00
|
|
|
return $data;
|
2017-01-11 15:31:43 +00:00
|
|
|
}
|
|
|
|
// Replacing invalid UTF-8 characters
|
|
|
|
// slow, small memory
|
|
|
|
//$data = mb_convert_encoding((string) $data, 'UTF-8', 'UTF-8');
|
|
|
|
// fast, large memory
|
2018-03-08 12:39:54 +00:00
|
|
|
$data = \htmlspecialchars_decode(\htmlspecialchars((string) $data, \ENT_SUBSTITUTE, 'UTF-8'));
|
2020-10-17 13:29:10 +00:00
|
|
|
// Canonical Decomposition followed by Canonical Composition
|
|
|
|
$data = Normalizer::normalize($data, Normalizer::FORM_C);
|
2017-01-11 15:31:43 +00:00
|
|
|
// Remove control characters
|
2020-10-27 06:31:10 +00:00
|
|
|
return \preg_replace('%(?:[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]|\xC2[\x80-\x9F])%', '', $data);
|
2017-01-11 15:31:43 +00:00
|
|
|
}
|
|
|
|
}
|