Intereting Posts
Как вы получаете Cronjob, выполняющий PHP-скрипт для работы более 30 секунд? после внесения или изменения пароля Пользователь не регистрируется в Yii2 Не удается найти ошибку при загрузке кода изображения php Вложенные объекты Symfony 3.0 не сохраняются Шифрование в Java и дешифрование в PHP с помощью Phpseclib Почему активный шаблон записи не работает с богатыми доменами? Почему PHPExcel не позволяет писать более 5000 строк Невозможно удалить утечку и утечку памяти Исключение исключений из Guzzle перенаправить пользователей на страницу входа в систему как добавить границу изображения вокруг изображения? Примечание: Неопределенное смещение: 0 в PHP: использование exit (); или умереть(); после заголовка («Местоположение:»); Сценарий Python не выполняется должным образом из Php Как предварительно обработать локальный файл CSV перед загрузкой на сервер?

Как создавать и использовать nonces

Я запускаю веб-сайт, и есть система подсчета очков, которая дает вам очки за количество раз, когда вы играете в игру.

Он использует хеширование, чтобы доказать целостность HTTP-запроса для подсчета очков, чтобы пользователи ничего не могли изменить, однако, как я боялся, может случиться, кто-то понял, что им не нужно его менять, им просто нужно было получить высокий балл и дублировать http-запрос, заголовки и все.

Раньше мне было запрещено защищать от этой атаки, потому что это считалось маловероятным. Однако теперь, когда это произошло, я могу. HTTP-запрос берется из флеш-игры, а затем проверяется php и php, вводит их в базу данных.

Я уверен, что нонс решит проблему, но я не совсем уверен, как ее реализовать. Что такое обычный и безопасный способ настройки системы nonce?

На самом деле это довольно легко сделать … Для этого есть несколько библиотек:

  1. Библиотека PHP Nonce
  2. Библиотека OpenID Nonce

Или, если вы хотите написать свой собственный, это довольно просто. Использование страницы WikiPedia в качестве точки перехода, в псевдокоде:

На стороне сервера вам нужны две вызываемые пользователем функции

getNonce() { $id = Identify Request //(either by username, session, or something) $nonce = hash('sha512', makeRandomString()); storeNonce($id, $nonce); return $nonce to client; } verifyNonce($data, $cnonce, $hash) { $id = Identify Request $nonce = getNonce($id); // Fetch the nonce from the last request removeNonce($id, $nonce); //Remove the nonce from being used again! $testHash = hash('sha512',$nonce . $cnonce . $data); return $testHash == $hash; } 

И на стороне клиента:

 sendData($data) { $nonce = getNonceFromServer(); $cnonce = hash('sha512', makeRandomString()); $hash = hash('sha512', $nonce . $cnonce . $data); $args = array('data' => $data, 'cnonce' => $cnonce, 'hash' => $hash); sendDataToClient($args); } 

Функция makeRandomString действительно просто должна вернуть случайное число или строку. Чем лучше случайность, тем лучше безопасность … Также обратите внимание на то, что, поскольку она передается прямо в хеш-функцию, детали реализации не имеют значения из запроса на запрос. Версия клиента и версия сервера не должны совпадать. Фактически единственным битом, который должен соответствовать 100%, является хеш-функция, используемая в hash('sha512', $nonce . $cnonce . $data); … Вот пример разумно защищенной функции makeRandomString

 function makeRandomString($bits = 256) { $bytes = ceil($bits / 8); $return = ''; for ($i = 0; $i < $bytes; $i++) { $return .= chr(mt_rand(0, 255)); } return $return; } 

Nonces – это банда червей.

Нет, действительно, одним из мотивов для нескольких записей CAESAR было создание схемы аутентифицированного шифрования, предпочтительно основанной на поточном шифре, которая устойчива к повторному использованию nonce. (Повторное использование nonce с AES-CTR, например, разрушает конфиденциальность вашего сообщения до степени, когда ученик первого курса может расшифровать его.)

Есть три основные школы мысли с нонцами:

  1. В криптографии с симметричным ключом: используйте увеличивающий счетчик, стараясь не использовать его повторно. (Это также означает использование отдельного счетчика для отправителя и получателя.) Для этого требуется программирование с сохранением состояния (например, сохранение nonce где-то, чтобы каждый запрос не начинался с 1 ).
  2. Состоятельные случайные числа. Создание случайного nonce, а затем запоминание его для подтверждения позже. Это стратегия, используемая для поражения атак CSRF, которая звучит ближе к тому, что здесь предлагается.
  3. Большие случайные числа без атак. Учитывая надежный генератор случайных чисел, вы можете почти гарантировать, что никогда не повторяйте nonce дважды в своей жизни. Это стратегия, используемая NaCl для шифрования.

Поэтому, имея в виду, основные вопросы:

  1. Какая из вышеупомянутых школ мысли наиболее важна для проблемы, которую вы пытаетесь решить?
  2. Как вы создаете nonce?
  3. Как вы проверяете nonce?

Создание Nonce

Ответ на вопрос 2 для любого случайного nonce заключается в использовании CSPRNG. Для проектов PHP это означает одно из:

  • random_bytes() для проектов PHP 7+
  • paragonie / random_compat , полифония PHP 5 для random_bytes()
  • ircmaxell / RandomLib , который является швейцарским армейским ножом утилит случайности, который в большинстве проектов, которые имеют дело с случайностью (например, сбрасывание пароля fir), должен рассмотреть возможность использования вместо того, чтобы переводить свои собственные

Эти двое морально эквивалентны:

 $factory = new RandomLib\Factory; $generator = $factory->getMediumStrengthGenerator(); $_SESSION['nonce'] [] = $generator->generate(32); 

а также

 $_SESSION['nonce'] []= random_bytes(32); 

Проверка Nonce

Stateful

Простые и рекомендуемые высказывания:

 $found = array_search($nonce, $_SESSION['nonces']); if (!$found) { throw new Exception("Nonce not found! Handle this or the app crashes"); } // Yay, now delete it. unset($_SESSION['nonce'][$found]); 

Не array_search() заменить array_search() на базу данных или memcached-поиск и т. Д.

Без гражданства (вот драконы)

Это сложная проблема: вам нужно каким-то образом предотвратить повторные атаки, но ваш сервер имеет общую амнезию после каждого HTTP-запроса.

Единственным разумным решением будет аутентификация даты / времени истечения срока действия, чтобы свести к минимуму эффективность повторных атак. Например:

 // Generating a message bearing a nonce $nonce = random_bytes(32); $expires = new DateTime('now') ->add(new DateInterval('PT01H')); $message = json_encode([ 'nonce' => base64_encode($nonce), 'expires' => $expires->format('Ymd\TH:i:s') ]); $publishThis = base64_encode( hash_hmac('sha256', $message, $authenticationKey, true) . $message ); // Validating a message and retrieving the nonce $decoded = base64_decode($input); if ($decoded === false) { throw new Exception("Encoding error"); } $mac = mb_substr($decoded, 0, 32, '8bit'); // stored $message = mb_substr($decoded, 32, null, '8bit'); $calc = hash_hmac('sha256', $message, $authenticationKey, true); // calcuated if (!hash_equals($calc, $mac)) { throw new Exception("Invalid MAC"); } $message = json_decode($message); $currTime = new DateTime('NOW'); $expireTime = new DateTime($message->expires); if ($currTime > $expireTime) { throw new Exception("Expired token"); } $nonce = $message->nonce; // Valid (for one hour) 

Тщательный наблюдатель заметит, что это в основном нестандартный вариант JSON Web Tokens .

Один из вариантов (который я упомянул в комментарии) – это запись игрового процесса и воспроизведение его в защищенной среде.

Другое дело – случайным образом или в определенное время записывать некоторые, казалось бы, невинные данные, которые позже могут быть использованы для проверки его на сервере (например, внезапное ожидание идет от 1% до 100% или оценка от 1 до 1000, что указывает на чит ). При наличии достаточного количества данных мошеннику может быть нецелесообразно пытаться подделать его. И тогда, конечно, реализуйте тяжелое запрещение :).

Невозможно предотвратить обман. Вы можете только усложнить ситуацию.

Если кто-то пришел сюда, ища библиотеку PHP Nonce: я не рекомендую использовать первый, заданный ircmaxwell .

Первый комментарий на веб-сайте описывает недостаток дизайна:

Функция nonce хороша для одного определенного временного окна, т. Е. Чем ближе пользователь добирается до конца этих окон, тем меньше времени он или она должен отправить в форму, возможно, менее одной секунды

Если вы ищете способ генерации Nonces с четко определенным временем жизни, посмотрите на NonceUtil-PHP .