Как создавать и использовать специальные слова
Я запускаю веб-сайт, и есть система подсчета очков, которая дает вам очки за количество раз, когда вы играете в игру.
Он использует хэширование, чтобы доказать целостность http-запроса для подсчета очков, поэтому пользователи не могут ничего изменить, однако, как я опасался, кто-то понял, что им не нужно было его менять, им просто нужно было получить высокий балл и дублировать http-запрос, заголовки и все.
ранее мне было запрещено защищать от это нападение, потому что это считалось маловероятным. Однако теперь, когда это произошло, я могу. Http-запрос исходит из флеш-игры, а затем проверяется php и php вводит его в базу данных.
Я уверен, что nonces решит эту проблему, но я не совсем уверен, как их реализовать. Что является общим, и надежный способ установки системы извращенец?
4 ответов:
это на самом деле довольно легко сделать... Есть несколько библиотек, чтобы сделать это для вас:
или если вы хотите написать свой собственный, это очень просто. Используя Википедия страницы как точка прыжка, в псевдокоде:
на стороне сервера вам нужны две клиентские вызываемые функции
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);... Вот пример достаточно безопасного ...function makeRandomString($bits = 256) { $bytes = ceil($bits / 8); $return = ''; for ($i = 0; $i < $bytes; $i++) { $return .= chr(mt_rand(0, 255)); } return $return; }
специальные слова являются трудной.
нет, действительно, одна из мотиваций для нескольких Цезарь записи должны были разработать аутентифицированную схему шифрования, предпочтительно основанную на потоковом шифре, который устойчив к повторному использованию nonce. (Повторное использование nonce с AES-CTR, например, разрушает конфиденциальность вашего сообщения до такой степени, что студент первого курса программирования может его расшифровать.)
есть три основные школы мысли с специальные слова:
- в криптографии с симметричным ключом: используйте увеличивающийся счетчик, стараясь никогда не использовать его повторно. (Это также означает использование отдельного счетчика для отправителя и получателя.) Для этого требуется Программирование с сохранением состояния (т. е. хранение nonce где-то, чтобы каждый запрос не начинался с
1).- состояние случайных nonces. Создание случайного nonce, а затем запоминание его для проверки позже. это стратегия, используемая для поражения атак CSRF, что звучит ближе к тому, что просят здесь.
- большие безгосударственные случайные nonces. Учитывая безопасный генератор случайных чисел, вы можете почти гарантировать, что никогда не повторите nonce дважды в своей жизни. Это стратегия, используемая NaCl для шифрования.
Итак, имея это в виду, основные вопросы, которые нужно задать:
- какие из вышеперечисленных школ мысли наиболее актуальны для проблемы, которую вы пытаетесь решить?
- как вы генерируете nonce?
- как вы проверяете nonce?
генерировать случайный код
ответ на вопрос 2 для любого случайного nonce заключается в использовании CSPRNG. Для PHP проектов это означает одно из:
random_bytes()для PHP 7+ проектов- paragonie / random_compat, PHP 5 polyfill для
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()с базой данных или 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('Y-m-d\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.
Comments