Мне нужна форма, в которой пользователь может изменить пароль. Я могу зашифровать пароль, однако, когда он выбирается из базы данных (исходный пароль говорит "тест"), он не распознает его.
Это когда пароль был зашифрован в db. я проверяю, соответствует ли введенный пароль в форме паролю в БД:
SELECT * from table where password = md5('$typed_password')
Вот как это зашифровано:
UPDATE table set field = md5('$typed_password' )
Как мой выбор может работать так, чтобы, когда пользователь вводит его в форме, распознавался исходный?
во-первых: MD5 - это криптографическая хэш-функция, а не обязательно метод шифрования. Хэш предназначен для выполнения только в одном направлении и не может быть изменен в обратном направлении. (Это хорошая вещь)
Однако MD5 криптографически взломан (больше не считается безопасным); вы должны использовать другую хеш-функцию (предпочтительно Bcrypt-хеш или хотя бы SHA256)
Глядя на код, я вижу несколько неправильных вещей:
Я действительно надеюсь, что $typed_password правильно очищен или вас ждет SQL-injection.
Вы пытаетесь выбрать всех пользователей из таблицы с одинаковым паролем.
Самый простой (и, вероятно, лучший) способ создания паролей - использование стандартной библиотеки: Переносимый пароль PHP. хеширования и убедитесь, что вы используете алгоритм CRYPT_BLOWFISH.
require('PasswordHash.php');
$pwdHasher = new PasswordHash(8, FALSE);
// $hash is what you would store in your database
$hash = $pwdHasher->HashPassword( $password );
// $hash would be the $hash stored in your database for this user
$checked = $pwdHasher->CheckPassword($password, $hash);
if ($checked) {
echo 'password correct';
} else {
echo 'wrong credentials';
}
запросы на сохранение/проверку/обновление должны быть привязаны к идентификатору пользователя:
// Insert query
$query = "INSERT INTO users VALUES({$userId}, '{$username}', '{$hash}')";
// Select query
$query = "SELECT hash FROM users WHERE userId = {$userId}";
// Update query
$query = "UPDATE users SET hash = '{$hash}' WHERE userId = {$userId}";
И затем вы должны использовать параметризованные запросы вместо прямой передачи значения переменных в запрос.
Я понимаю, что это много информации сразу, но очень важно выучить это, если вы не хотите, чтобы ваш скрипт был взломан почти каждым программистом.
Ответ 2 · рейтинг 1 · Michal M
Почему бы не зашифровать пароль в PHP, а затем INSERT уже зашифрованный. То же самое с SELECT.
So:
$enc_passwd = md($typed_password);
$sql = "SELECT * FROM table WHERE password = '$enc_passwd')";
аналогично с UPDATE
(почему не INSERT?)
Ответ 3 · Daren Schwenke
Недавний пост о паролях I немного отклонился от темы и много об этом рассказал. Лакомый кусочек:
Как только вы довольны паролем, который они выбрали, сначала зашифруйте его с помощью PHP, а затем сохраните. Следующая функция шифрования пароля тоже не моя идея, но решает ряд проблем. Шифрование в PHP не позволяет людям на общем сервере перехватывать ваши незашифрованные пароли. Добавление чего-то для каждого пользователя, что не изменится (я использую электронную почту, так как это имя пользователя для моих сайтов) и добавление хэша (SALT - это короткая постоянная строка, которую я меняю для каждого сайта), повышает устойчивость к атакам. Поскольку SALT находится внутри пароля, а пароль может быть любой длины, становится практически невозможно атаковать его с помощью радужной таблицы. С другой стороны, это также означает, что люди не могут изменить свою электронную почту, и вы не можете изменить SALT, не аннулировав все пароли.
function password_crypt($email,$toHash) {
$password = str_split($toHash,(strlen($toHash)/2)+1);
return hash('sha256', $email.$password[0].SALT.$password[1]);
}
Итак, при первом вводе пароля пользователя в псевдокоде:
define(SALT,'blah');
$hashed_password = password_crypt($email,$password);
INSERT INTO users (email,hashed_password) VALUES ($email,$hashed_password);
Затем, чтобы проверить последующий вход в псевдокод:
define(SALT,'blah');
$user_hashed_password = password_crypt($_POST['username'],$_POST['password']);
SELECT email FROM users WHERE email = ? AND hashed_password = $user_hashed_password LIMIT 1
Если вы получите строку обратно, действительный логин.