Использование хеша в PhP

Я пытаюсь написать код проверки на PhP, выполнив следующие действия...

Код подтверждения рассчитывается по:

  1. Код подтверждения = целое число(SHA256(хэш)[-2:-1]) mod 10000
  2. Вычислите SHA256 из хеша, извлеките из результата 2 крайних правых байта, интерпретируйте их как целое число без знака с обратным порядком байтов и возьмите последние 4 цифры в десятичной форме для отображения. Здесь всегда используется SHA256.
  3. Обратите внимание, что хэш — это реальное значение хеш-байта, а не форма Base64 или шестнадцатеричное представление.

Пока у меня есть этот код, но он работает не так, как я надеялся:

function calculateVcode($hashString) {
  $md = hash_init('sha256');
  $hash = base64_decode($hashString);
  hash_update($md, $hash);
  $hash = hash_final($md, true);
  $last = substr($hash, -2);
  $code = bindec($last);
  return substr(strval($code), -4);
}

$hashString = "Demo string for Authentication";
$md5Hash = md5($hashString);
$result = calculateVcode($md5Hash);`

Есть идеи, как заставить это работать, или я совершенно на неправильном пути?

Результат может быть таким: Текст, используемый для создания хэш-строки «Аутентификация приложения Auðkenni»

Сгенерирована хэш-строка n/kRNhXaZ2jFKv8KlQX7ydgedXUmVy8b2O4xNq2ZxHteG7wOvCa0Kg3rY1JLOrOBXYQm+z2FRVwIv47w8gUb5g==

Проверочный код, рассчитанный на основе хэша 4141

Почему вы используете base64_decode() для результата md5()?

Progman 04.05.2024 18:34
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
1
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для правильного хеширования SHA-256 вам нужны необработанные двоичные данные, которые представляет MD5, а не их закодированная или строковая версия. Если вы начинаете с хеш-строки MD5, вам следует преобразовать эту строку обратно в двоичный формат, если она закодирована в шестнадцатеричном формате, или убедиться, что вы имеете дело непосредственно с двоичными данными.

Кроме того, способ преобразования последних двух байтов в целое число не совсем верен. Функция bindec() не предназначена для преобразования двоичных данных непосредственно в целые числа, поскольку она интерпретирует двоичную строку, а не необработанные байты.

Как только они будут исправлены, вы должны ожидать ожидаемых результатов:

function calculateVcode($hashString) {
    // Assume $hashString is already a proper byte sequence
    $hash = hash('sha256', $hashString, true); // true for raw binary output
    $lastTwoBytes = substr($hash, -2); // Get the last 2 bytes
    $value = unpack("n", $lastTwoBytes); // Unpack as a big-endian ushort (16-bit int)
    $code = $value[1] % 10000; // get last 4 digits
    return $code;
}

$originalText = "Auðkenni APP Authentication";
$hashString = base64_decode("n/kRNhXaZ2jFKv8KlQX7ydgedXUmVy8b2O4xNq2ZxHteG7wOvCa0Kg3rY1JLOrOBXYQm+z2FRVwIv47w8gUb5g= = ");
$result = calculateVcode($hashString);
echo "Verification code: " . $result . "\n";

Кстати: ваш метод получения последних 4 цифр может привести к ошибкам, если преобразованное целое число имеет длину менее 4 цифр.


как лучше всего создать необработанную хэш-строку?

Я бы сгенерировал необработанный (в двоичной форме) хэш SHA-512 ваших данных. Затем закодируйте его в Base64, что необходимо для передачи или сохранения хеша в текстовом формате. Когда вам понадобится использовать этот хэш для дальнейшей обработки (например, для расчета проверочного кода), вы декодируете его из Base64 обратно в исходную необработанную двоичную форму:

function createBase64EncodedSHA512(string $input): string {
    $rawHash = hash('sha512', $input, true);
    return base64_encode($rawHash);
}

function calculateVcodeFromBase64SHA512(string $base64EncodedHash): int {
    $hashBytes = base64_decode($base64EncodedHash);
    $hash = hash('sha256', $hashBytes, true);
    $lastTwoBytes = substr($hash, -2);
    $value = unpack("n", $lastTwoBytes);
    $code = $value[1] % 10000;
    return $code;
}

Пример использования

$inputData = "Your data here";
$base64SHA512 = createBase64EncodedSHA512($inputData);
$verificationCode = calculateVcodeFromBase64SHA512($base64SHA512);
echo "Verification Code: " . $verificationCode . "\n";

Спасибо, Марцин, отличный вклад, и я вижу свои ошибки. Но что касается ввода в функцию, как лучше всего создать необработанную хэш-строку? В инструкциях говорится: вам нужно будет предоставить хеш-строку для использования. Таким образом вы можете рассчитать код подтверждения на своей стороне, чтобы отобразить его на вашем веб-сайте, чтобы его мог увидеть ваш пользователь. Хэш-строка должна иметь тип SHA512. Обратите внимание, что хеш-строка должна быть в формате Base64.

Steve 04.05.2024 20:13

Спасибо, Марчин! Абсолютно великолепно, вы решили для меня эту загадку.

Steve 04.05.2024 23:10

Другие вопросы по теме