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

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

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

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

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

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

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


person user179780    schedule 24.10.2009    source источник


Ответы (3)


во-первых: 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}";

И затем вы должны использовать параметризованные запросы вместо прямой передачи значения переменных в запрос.

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

person Jacco    schedule 24.10.2009
comment
если хорошо, не могли бы вы уточнить пункты 1 и 3. Я не совсем понимаю, что вы имеете в виду. Спасибо - person user179780; 25.10.2009
comment
Спасибо за всю информацию буду разбираться. Причина, по которой я делаю это, заключается в том, что если пользователь повторно входит в систему, ожидается, что он войдет в систему с паролем, который он ввел в форме. Этот пароль может быть распознан только в том случае, если он будет преобразован обратно в исходный формат. Это правильно то, что я думаю? Пожалуйста, поправьте меня, если я ошибаюсь, в данный момент я не читал криптографическую хеш-функцию. - person user179780; 25.10.2009
comment
Это работает, даже не зная, какой пароль был через хэш. Вы хешируете их исходный пароль, снова перехешируете его и сравниваете хэши вместо паролей. - person Daren Schwenke; 25.10.2009
comment
$typed_password не нужно дезинфицировать, так как он все равно хэшируется. и хэши почти наверняка нельзя использовать в SQL-инъекциях - person knittl; 25.10.2009
comment
md5('$typed_password') с $typed_password, установленным как: x') AND 1=1 --, может сломать систему. - person Jacco; 25.10.2009

Почему бы не зашифровать пароль в PHP, а затем INSERT уже зашифрованный.
То же самое с SELECT.

So:

$enc_passwd = md($typed_password);
$sql = "SELECT * FROM table WHERE password = '$enc_passwd')";

аналогично с UPDATE

(почему не INSERT?)

person Michal M    schedule 24.10.2009
comment
Вы по-прежнему выбираете каждого пользователя с определенным паролем, хэш пароля не солен, а хеш-функция (MD5) криптографически взломана. - person Jacco; 25.10.2009
comment
@жакко. Хотя это правда, он пытается донести мысль, почему бы не позволить php делать всю работу вместо mysql? Ему не нужно использовать md5. PHP поддерживает 34 других хеш-алгоритма и, начиная с версии 5.1.2. us3.php.net/manual/en/function.hash-algos. php - person txyoji; 25.10.2009

Недавний пост о паролях 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

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

person Daren Schwenke    schedule 24.10.2009
comment
спасибо за предложения, я прочитаю это и попробую. Спасибо еще раз всем - person user179780; 25.10.2009
comment
Соль должна меняться для каждого хешированного пароля. Использование постоянного значения для каждого сайта является неправильным. - person Jacco; 25.10.2009
comment
Я предполагаю, что вы никогда не читали его. Он меняется для каждого хешированного пароля. Я использую две соли. Один из них меняется для каждого сайта, чтобы предотвратить радугу между сайтами, а другой — для каждого пользователя. - person Daren Schwenke; 25.10.2009
comment
Соль должна быть случайной, чтобы быть эффективной, а не полученной из каких-то пользовательских данных. Использование случайной соли гарантирует, что хэш-значение эффективно отличается для каждого сохраненного хэша, будь то в вашей собственной системе или в разных системах. Это также гарантирует, что изменение адреса электронной почты не сделает пароль недействительным. Короче говоря: порекомендуйте/используйте проверенную библиотеку, потому что существует слишком много возможностей потерпеть неудачу. - person Jacco; 25.10.2009
comment
Раньше я использовал случайную строку, сгенерированную при присоединении пользователей. Он был сохранен в их записи пользователя. В любом случае, если злоумышленник сможет получить мои хешированные пароли, он получит мою первую соль, будь то электронная почта или случайное. Я согласен, что энтропия немного увеличивается со случайным. На какую проверенную библиотеку вы бы ссылались? - person Daren Schwenke; 25.10.2009
comment
Хорошо, я продан. :) Хорошее хеширование, небольшой размер, определяемые вычислительные затраты и обратная совместимость, если я включу это. - person Daren Schwenke; 25.10.2009
comment
Спасибо Дарен и Джакко, оба предоставили полезные отзывы. - person user179780; 28.10.2009