[PHP] Правильное шифрование паролей

Автор: urmaul
10.07.2012 20:49

Для затравки: вы, наверное, уже прочитали, как пользоваться md5. Так вот: md5 — это не серьезно. И sha-1 — это несерьезно. Сейчас опишу, почему. И расскажу как можно просто шифровать пароли гораздо надежнее.

Зачем мы шифруем пароли

Содержимое вашей базы данных рано или поздно окажется в грязных мерзких ручонках хакеров. И если они получат логины и пароли ваших пользователей, а тем более — пароль администратора, злоумышленник сможет надеелать много чего плохого.

Поэтому пароли не хранят в открытом виде. Обычно для этого используют хеши. Их идея в том, что из исходной строки получить хеш легко, а из хеша исходную строку - тяжело. Вообще не получить. Можно только найти строку с таким же хешем и надеяться, что это та же строка.

Обычно для хеширования паролей используют функции md5 и sha1. Они достаточно простые и быстрые. Но взламывать их тоже несложно. Если не верите — погуглите "21232f297a57a5a743894a0e4a801fc3". Использование соли несколько усложняет взлом, но не намного. Основная проблема остается: если хакер сольет вашу базу из десяти тысяч паролей — он будет подбирать все десять тысяч паролей одновнеменно. И это будет не намного сложнее, чем подобрать один пароль.

Как защищать пароли надежнее

В php есть специальная функция для хеширования паролей — crypt. Она используется для хеширования пароля с солью и для проверки соответствия пароля хешу.

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

Генерация соли в php

Для удобной работы с паролями одни добрые ребята разработали библиотеку phpass (Portable PHP password hashing framework). Она позволяет указывать сложность соли (влияет на скорость вычисления хеша) и подбирает тот алгоритм, который поддерживатся php на вашем сервере.

У этой библиотеки не самый удобный интерфейс. Совсем не удобный. Поэтому стоит найти подходящий враппер для вашего фреймворка. Если же собираетесь работать с ней напрямую — вам стоит посмотреть на примеры кода, которые я честно спер с гитхаба.

Сохранение пароля

 
require("PasswordHash.php");
 
$hasher = new PasswordHash(8, false);
 
// In a typical situation, you will have a form with the "method" attribute set to "post" with an input of name "password"
$password = $_POST["password"];
 
// Passwords should never be longer than 72 characters to prevent DoS attacks
if (strlen($password) > 72) { die("Password must be 72 characters or less"); }
 
// The $hash variable will contain the hash of the password
$hash = $hasher->HashPassword($password);
 
if (strlen($hash) >= 20) {
 
 // store the value of $hash in a database or something
 
} else {
 
 // something went wrong
 
}
 

Логин

 
require("PasswordHash.php");
 
$hasher = new PasswordHash(8, false);
 
// In a typical situation, you will have a form with the "method" attribute set to "post" with an input of name "password"
$password = $_POST["password"];
 
// Passwords should never be longer than 72 characters to prevent DoS attacks
if (strlen($password) > 72) { die("Password must be 72 characters or less"); }
 
// Just in case the hash isn't found
$stored_hash = "*";
 
// Retrieve the hash that you stored earlier
$stored_hash = "this is the hash we stored earlier";
 
// Check that the password is correct, returns a boolean
$check = $hasher->CheckPassword($password, $stored_hash);
 
if ($check) {
 
 // passwords matched! show account dashboard or something
 
} else {
 
 // passwords didn't match, show an error
 
}
 

Тонкости

У конструктора PasswordHash два аргумента. Первый — сложность хеша, число от 4 до 31. Второй — стоит ли хешам поддерживать старые версии php, булевое значение.

Пароль не должен быть длиннее 72 символов чтобы не перегружать сервер.

Если хеш получился короче 20 символов — что-то поломалось.

Что получилось

Использование хешей на основе функции crypt гораздо менее удобно, чем md5. Но оно себя оправдывает, безопасность вашей системы значительно усилится. Хотя и не стоит думать, что после этого вы будете в безопасности. Вы никогда не будете в безопасности.

UPD: В Yii 1.1.14 появился хелпер для этих же целей. Теперь пользовательям этого фреймворка не надо ставить отдельную либу.

Обновлено 03.02.2014 16:39

 

Комментарии  

 
#1 anon 11.07.2012 14:36
те же добрые ребята с openwall.com написали и старую добрую утилиту john the ripper, которой такие хеши ломаются.
но скорость перебора таких хешей минимальна.
Цитировать
 
 
#2 anon 26.06.2013 00:02
В версии 5.5.0 теперь есть функция
password_hash
Цитировать
 
 
#3 http://blogsen.ovh 13.04.2017 14:34
Therefore, people direct more time online.
Цитировать
 
 
#4 g5g.info 04.05.2017 12:06
Thanks for helping out, great information.
Цитировать
 
 
#5 Kamil Zakrzewski 30.05.2017 19:18
Ahaa, its fastidious conversation regarding this post here at this
blog, I have read all that, so now me also commenting here.
Цитировать
 
 
#6 Oswald Stankowski 02.06.2017 08:03
It's truly very complicated in this full of activity life to listen news on TV,
thus I simply use the web for that purpose, and take the most up-to-date information.
Цитировать
 
 
#7 Roch Pliszka 09.06.2017 13:12
I feel this is one of the so much vital information for me.
And i am satisfied studying your article. But should statement on some general things, The site taste
is ideal, the articles is in reality excellent : D. Just right
job, cheers
Цитировать
 
 
#8 Hubert Ptaszek 10.06.2017 06:28
Hi, the whole thing is going perfectly here and ofcourse every one is
sharing data, that's really good, keep up writing.
Цитировать
 
 
#9 Martin Fornal 11.06.2017 03:19
I visited several blogs except the audio quality
for audio songs present at this site is really wonderful.
Цитировать
 
 
#10 Aleksander laski 12.06.2017 06:52
Hello, i feel that i saw you visited my website thus
i got here to return the favor?.I am trying to find issues to
improve my website!I assume its adequate to use a few of your ideas!!
Цитировать
 

Добавить комментарий


Защитный код
Обновить