Недавно я пытался реализовать свою собственную безопасность в сценарии входа в систему, который я наткнулся на Интернет. После попытки попытаться научиться создавать собственный скрипт для создания соли для каждого пользователя, я наткнулся на password_hash.
Из того, что я понимаю (основываясь на чтении на этой странице: http://php.net/manual/en/faq.passwords.php ), соль уже сгенерирована в строке при использовании пароля. Это правда?
Еще один вопрос, который у меня был, было бы разумно иметь 2 соли? Один непосредственно в файле и один в БД? Таким образом, если кто-то компрометирует вашу соль в БД, у вас все еще есть один непосредственно в файле? Я читал здесь, что хранение солей никогда не является умной идеей, но это всегда путало меня, что люди подразумевали под этим.
Использование password_hash – это рекомендуемый способ хранения паролей. Не отделяйте их от БД и файлов.
Допустим, у нас есть следующий ввод:
$password = $_POST['password'];
Я не проверяю ввод только ради понимания концепции.
Сначала вы вводите пароль:
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
Затем см. Вывод:
var_dump($hashed_password);
Как вы видите, это хешировано. (Я предполагаю, что вы сделали эти шаги).
Теперь вы храните этот hashed_password в своей базе данных, а затем скажем, когда пользователь просит их войти в систему. Вы проверяете ввод пароля с этим хеш-значением в базе данных, делая следующее:
// Query the database for username and password // ... if(password_verify($password, $hashed_password)) { // If the password inputs matched the hashed password in the database // Do something, you know... log them in. } // Else, Redirect them back to the login page.
Да, вы поняли это правильно, функция password_hash () будет генерировать соль сама по себе и включает ее в полученное хеш-значение. Сохранение соли в базе данных абсолютно корректно, оно выполняет свою работу, даже если известно.
// Hash a new password for storing in the database. // The function automatically generates a cryptographically safe salt. $hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT); // Check if the hash of the entered login password, matches the stored hash. // The salt and the cost factor will be extracted from $existingHashFromDb. $isPasswordCorrect = password_verify($_POST['password'], $existingHashFromDb);
Вторая соль, которую вы упомянули (тот, который хранится в файле), на самом деле является перечным или серверным ключом. Если вы добавите его перед хэшированием (например, соль), добавьте перец. Однако есть лучший способ, вы можете сначала вычислить хэш, а затем зашифровать (двухсторонний) хеш с помощью серверного ключа. Это дает вам возможность изменить ключ при необходимости.
В отличие от соли, этот ключ должен храниться в секрете. Люди часто смешивают его и пытаются скрыть соль, но лучше дать соль сделать свою работу и добавить секрет с помощью ключа.
Да, это правда. Почему вы сомневаетесь в php faq для функции? 🙂
Результат выполнения функции password_hash()
состоит из четырех частей:
Итак, как вы видите, хэш является его частью.
Конечно, у вас может быть дополнительная соль для дополнительного уровня безопасности, но я, честно говоря, считаю, что это избыток в обычном приложении php. Алгоритм bcrypt по умолчанию хорош, и, пожалуй, еще лучше, чем опция blowfish.
Никогда не используйте md5 () для защиты вашего пароля, даже с солью, это всегда опасно!
Сделайте свой пароль с последними алгоритмами хеширования, как показано ниже.
<?php // Your original Password $password = '121@121'; //PASSWORD_BCRYPT or PASSWORD_DEFAULT use any in the 2nd parameter /* PASSWORD_BCRYPT always results 60 characters long string. PASSWORD_DEFAULT capacity is beyond 60 characters */ $password_encrypted = password_hash($password, PASSWORD_BCRYPT); ?>
Для сопоставления с зашифрованным паролем базы данных и введенным пользователем паролем используйте следующую функцию.
<?php if (password_verify($password_inputted_by_user, $password_encrypted)) { // Success! echo 'Password Matches'; }else { // Invalid credentials echo 'Password Mismatch'; } ?>
Если вы хотите использовать свою соль, используйте свою собственную созданную функцию для нее, просто следуйте ниже, но я не рекомендую это, поскольку она найдена устаревшей в последних версиях PHP.
прочитайте это http://php.net/manual/en/function.password-hash.php перед использованием ниже кода.
<?php $options = [ 'salt' => your_custom_function_for_salt(), //write your own code to generate a suitable & secured salt 'cost' => 12 // the default cost is 10 ]; $hash = password_hash($your_password, PASSWORD_DEFAULT, $options); ?>
Надеюсь, что все это поможет!
Я создал функцию, которую я все время использую для проверки пароля и создания паролей, чтобы сохранить их в базе данных mysql. Он использует случайно сгенерированную соль, которая более безопасна, чем использование статической соли.
function secure_password($user_pwd, $multi) { /* secure_password ( string $user_pwd, boolean/string $multi ) *** Description: This function verifies a password against a (database-) stored password's hash or returns $hash for a given password if $multi is set to either true or false *** Examples: // To check a password against its hash if(secure_password($user_password, $row['user_password'])) { login_function(); } // To create a password-hash $my_password = 'uber_sEcUrE_pass'; $hash = secure_password($my_password, true); echo $hash; */ // Set options for encryption and build unique random hash $crypt_options = ['cost' => 11, 'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)]; $hash = password_hash($user_pwd, PASSWORD_BCRYPT, $crypt_options); // If $multi is not boolean check password and return validation state true/false if($multi!==true && $multi!==false) { if (password_verify($user_pwd, $table_pwd = $multi)) { return true; // valid password } else { return false; // invalid password } // If $multi is boolean return $hash } else return $hash; }