Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Php шифрование sql

Автор вопроса: user179780Ответов: 3

Мне нужна форма, в которой пользователь может изменить пароль. Я могу зашифровать пароль, однако, когда он выбирается из базы данных (исходный пароль говорит "тест"), он не распознает его.

Это когда пароль был зашифрован в db. я проверяю, соответствует ли введенный пароль в форме паролю в БД:

SELECT * from table where password = md5('$typed_password')

Вот как это зашифровано:

UPDATE table set field = md5('$typed_password' )

Как мой выбор может работать так, чтобы, когда пользователь вводит его в форме, распознавался исходный?

encryptionphpsecurityhash

Ответы

Ответ 1 · рейтинг 4 · Jacco

во-первых: MD5 - это криптографическая хэш-функция, а не обязательно метод шифрования. Хэш предназначен для выполнения только в одном направлении и не может быть изменен в обратном направлении. (Это хорошая вещь)

Однако MD5 криптографически взломан (больше не считается безопасным); вы должны использовать другую хеш-функцию (предпочтительно Bcrypt-хеш или хотя бы SHA256)

Глядя на код, я вижу несколько неправильных вещей:

  1. ваш пароль не соленый
  2. Я действительно надеюсь, что $typed_password правильно очищен или вас ждет SQL-injection.
  3. Вы пытаетесь выбрать всех пользователей из таблицы с одинаковым паролем.

Самый простой (и, вероятно, лучший) способ создания паролей - использование стандартной библиотеки: Переносимый пароль 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

Если вы получите строку обратно, действительный логин.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы