Как использовать соль и хэш в логине?

Я хочу использовать соль и хеш для создания безопасного входа в систему. Я стараюсь следовать этот урок и написать собственный код, но он всегда возвращает false. Вот мой код:

require_once 'application/third_party/Secure-Login/classes/Hashing.php';
require_once 'application/third_party/Secure-Login/classes/Salt.php';
$password = Hashing::create_hash('123456', Salt::random(12));
$old = '$2a$10$zuzycDw3Ack2cCoL3ds1sudJ2WioZ87.75ErLZVcZyh4d1hS2rHFu';

if (Hashing::validate($password, $old, Salt::random(12))) {
echo true;
} else {
echo false;
}

И два класса, которые я включил:

<?php

class Hashing {

function __construct() {}

/**
* @param string $pass The user submitted password
* @param string $hashed_pass The hashed password pulled from the database
* @param string $salt The salt pulled from the database
* @param string $hash_method The hashing method used to generate the hashed password
*/
static function validate($pass, $hashed_pass, $salt, $hash_method = 'sha1') {
if (function_exists('hash') && in_array($hash_method, hash_algos())) {
return ($hashed_pass === hash($hash_method, $salt . $pass));
}
return ($hashed_pass === sha1($salt . $pass));
}

/**
* Generates a secure, pseudo-random password with a safe fallback.
*/
static function pseudo_rand($length) {
if (function_exists('openssl_random_pseudo_bytes')) {
$is_strong = false;
$rand = openssl_random_pseudo_bytes($length, $is_strong);
if ($is_strong === true) {
return $rand;
}
}
$rand = '';
$sha = '';
for ($i = 0; $i < $length; $i++) {
$sha = hash('sha256', $sha . mt_rand());
$chr = mt_rand(0, 62);
$rand .= chr(hexdec($sha[$chr] . $sha[$chr + 1]));
}
return $rand;
}

/**
* Creates a very secure hash. Uses blowfish by default with a fallback on SHA512.
*/
static function create_hash($string, $salt = '', $hash_method = 'sha1', $stretch_cost = 10) {
$salt = Hashing::pseudo_rand(128);
$salt = substr(str_replace('+', '.', base64_encode($salt)), 0, 22);
if (function_exists('hash') && in_array($hash_method, hash_algos())) {
return crypt($string, '$2a$' . $stretch_cost . '$' . $salt);
}
return Hashing::_create_hash($string, $salt);
}

/**
* Fall-back SHA512 hashing algorithm with stretching.
*/
static function _create_hash($password, $salt) {
$hash = '';
for ($i = 0; $i < 20000; $i++) {
$hash = hash('sha512', $hash . $salt . $password);
}
return $hash;
}

}

<?php

class Salt {

public static function random($len = 8) {
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`~!@#$%^&*()-=_+';
$l = strlen($chars) - 1;
$str = '';
for ($i = 0; $i < $len; ++$i) {
$str .= $chars[rand(0, $l)];
}
return $str;
}

}

Пожалуйста, проверьте, помогите мне! Я не знаю, где это не так и как это работает. Большое спасибо!

0

Решение

Есть много проблем с вашим кодом, поэтому я сильно предлагаем использовать функции password_hash () а также password_verify () делать перемешивание.

Поскольку вы сказали, что хотите понять, как это работает, вот несколько советов:

static function create_hash($string, $salt = '', $hash_method = 'sha1', $stretch_cost = 10) {
$salt = Hashing::pseudo_rand(128);
$salt = substr(str_replace('+', '.', base64_encode($salt)), 0, 22);
if (function_exists('hash') && in_array($hash_method, hash_algos())) {
return crypt($string, '$2a$' . $stretch_cost . '$' . $salt);
}
return Hashing::_create_hash($string, $salt);
}

Этот метод сначала пытается использовать crypt() что хорошо, потому что он генерирует хеш BCrypt. Параметр стоимости потерпит неудачу, если он меньше 10, и соль может быть сгенерирована небезопасно, и он использует слишком много энтропии из пула. Затем он проверяет, является ли hash() функции существуют, но эта функция вообще не предназначена для хэширования паролей и не имеет ничего общего с crypt ().

Позже для проверки вы не используете crypt()вместо того, чтобы проверить с hash() функция, это другой алгоритм, как и раньше. Тогда соль не может быть свободно выбрана для проверки пароля, вместо этого вам нужна та же соль, которая использовалась для генерации хеша, функция crypt () действительно включила эту соль в хеш-значение.

static function validate($pass, $hashed_pass, $salt, $hash_method = 'sha1') {
if (function_exists('hash') && in_array($hash_method, hash_algos())) {
return ($hashed_pass === hash($hash_method, $salt . $pass));
}
return ($hashed_pass === sha1($salt . $pass));
}

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

1

Другие решения

Если вы действительно хотите сделать свою жизнь проще. Вы можете пойти на PHPASS библиотека, которая предоставляет вам функции для использования. Вам просто нужно создать объект класса и использовать функции.

Проверьте эти ссылки:
Вы можете скачать библиотеку отсюда:
Скачать PHPASS

Вы можете получить больше информации здесь:
Пример использования библиотеки

1

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

Попробуйте следующий код:

$salt = Salt::random(12);
$password = Hashing::create_hash('123456', $salt);

Проверять:

if (Hashing::validate('123456', $password, $salt)) {
echo true;
} else {
echo false;
}

Конечно, вам нужно будет генерировать новую соль каждый раз, когда вы хотите хэшировать новый пароль.

0
По вопросам рекламы [email protected]