Как password_verify и doveadm pw -t проверить пароль без соли

в настоящее время я пытаюсь понять хэши и соли. Насколько я понимаю, не должно быть возможности проверить пароль, если у меня есть только пароль и сгенерированный хэш (который был сгенерирован со случайной солью). Итак, как функция password_verify в PHP может проверить мой пароль, если я не даю ей соль? Есть ли в фоновом режиме скрытая переменная, которая хранит ее для функций хеширования php?

И если это так, как можно

doveadm pw -t '{SHA512-CRYPT}$6$myhash...' -p "qwertz"

проверить это тоже, даже если я запускаю его на совершенно другом компьютере? Это инструмент, который поставляется с Dovecot (MDA).

Вот мой PHP-код, который создает случайную соль из 64 символов, объединяет ее с паролем, создает хэш и проверяет хэш через password_verify().

Я только сегодня начал работать над всем этим hash/salt/pepper, так что во всей моей мысли мог быть огромный изъян.

<?php
$password = "qwertz";
$salt = createSalt(64);
$hash = crypt($password, "$6$$salt");

if (password_verify($password, $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}


function createSalt($length){
    $chars = "IrhsYyLofUKj4caz0FDBCe2W9NRunTgQvp7qOXmS5GM3EJV6i8tAHdkPbxwl1Z";
    $salt="";
    for($i=0; $i < $length; $i++){
        $newchar = substr($chars, rand(0,strlen($chars)-1),1);
        $salt .= $newchar;
    }
    return $salt;
}
?>

person Sakkath    schedule 12.01.2018    source источник
comment
Я не думаю, что ваша соль в действии, так как вы используете соль на 6$$.   -  person Md Monjur Ul Hasan    schedule 12.01.2018
comment
password_hash и password_verify не требуют, чтобы вы сами добавляли пароль. Это обрабатывается внутри и возвращается как часть результирующего хэша. Эти две функции предназначены для защиты от идиотов :)   -  person Niet the Dark Absol    schedule 12.01.2018
comment
@MdMonjurUlHasan Monjur Ul Hasan $6$ был там по другой причине, без него тот же результат.   -  person Sakkath    schedule 12.01.2018


Ответы (2)


Хэш содержит несколько фрагментов информации. В этой статье объясняется формат, используемый Unix, но Я считаю, что функции пароля PHP используют аналогичный формат (если не тот же):

Само поле хэша состоит из трех разных полей. Они разделены символом «$» и представляют:

  • Некоторые символы, которые представляют собой криптографический механизм хеширования, используемый для генерации фактического хэша.
  • Случайно сгенерированная соль для защиты от атак радужного стола
  • Хэш, полученный в результате объединения пароля пользователя с сохраненной солью и запуска его через механизм хеширования, указанный в первом поле.

Он также может включать точные параметры алгоритма, используемые для генерации хэша, такие как стоимость алгоритма:

var_dump(password_hash('foo', PASSWORD_BCRYPT, [
    'cost' => 8,
]));
string(60) "$2y$08$7Z5bTz7xXnom8QsrbZ7uQetMLxOZ7WjuDkUYRIh73Ffa17GV1Tb7q"

Здесь $2y$08$ означает, что использовался Bcrypt стоимостью 8.

Если мы используем более новый Argon2, доступный в PHP/7.2, то параметров будет еще больше:

$argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0
person Álvaro González    schedule 12.01.2018
comment
Эй, спасибо за ваш ответ. В моем случае соль всегда имеет длину 16 байт и хранится между вторым и третьим $. $6$wMW8ASRU7sv3Wims$uMyN6a3UF/7SEVefsriAqCB3bPxynZ6zsuwV68tURvIyZhSKYO.1DIh9kRTzfBC6rnZiRiwrJ71/gBBtWHWfj0 - - wMW8ASRU7sv3Wims, кажется, соль. - person Sakkath; 12.01.2018

Некоторые предыстории ответа от @Álvaro González:

В руководстве по PHP предлагается использовать «password_hash» вместо функции «crypt», поскольку «password_hash» является оболочкой «crypt()» (поскольку он использует надежный хеш, генерирует сильную соль и автоматически применяет правильные раунды.)

«password_hash()» возвращает алгоритм, стоимость и соль как часть возвращаемого хэша. Поэтому вся информация, необходимая для проверки хэша, включена в него. Это позволяет функции «password_verify» проверять хэш без необходимости отдельного хранения соли или информации об алгоритме. : http://php.net/manual/en/function.password-verify.php

Поскольку «password_hash» является оболочкой для «crypt», «crypt» также делает то же самое, то есть возвращает алгоритм, стоимость и соль как часть возвращаемого хэша. и, таким образом, «password_verify» может проверить хэш.

Теперь, пожалуйста, проверьте ответ, данный @Álvaro González

person sudip    schedule 12.01.2018