md5() + соль. Хранение паролей в базе данных

В этой статье я расскажу как безопасно хранить пароли в базе данных

1 способ. Храним пароль как есть. Например, если ввели пароль "fuckoff", то он так и сохранится. Минус в том, что при взломе БД злоумышленник получает все пароли в явном виде.

хранение пароля в явном виде

2 способ. Храним пароль в зашифрованном виде, используя алгоритмы шифрования md5, sha1 и т.д. Например, md5('loveyou') = "f74a10e1d6b2f32a47b8bcb53dac5345"

пароль в md5

При взломе злоумышленник получит зашифрованные пароли и не сможет их расшифровать, т.к шифрование необратимое. Но он может методом перебора шифровать различные комбинации символов и, сравнивая полученный хеш с украденным хешом пароля, найти исходный пароль.

На первый взгляд кажется невозможным перебрать огромное количество комбинаций. Однако у большинства пользователей пароль представлен цифрами, словарными словами и другими простыми комбинациями символов. Поэтому задача упрощается (особенно, если пароль представлен цифрами). Кроме того, существуют сервисы, которые хранят терабайты хешей паролей (Rainbow tables). Например, сервис http://gdataonline.com/, содержит 1 133 000 000 паролей. Взлом пароля "loveyou" занимает сотые доли секунды

Rainbow tables

3 способ. Храним пароль в зашифрованном виде, но добавляя несколько случайных символов, уникальных для каждого пользователя (так называемая соль). А еще лучше хранить двойной md5 с солью. Взломать такой вышеупомянутым способом практически невозможно. В таблице user нам потребуется два поля:
1) поле salt для хранения соли
2) поле password для хранения хеша от md5(md5(пароль)+соль) .

пароль с солью

Например, авторизация пользователя

// $user – информация о пользователе из таблицы user
if (md5(md5($_POST['password']).$user['salt']) == $user['password']) {
    // проверка прошла успешно. логиним!
}

Где брать соль? Необходимо в скрипте регистрации генерировать соль для каждого нового пользователя. Для этого можно воспользоваться следующей функцией

function generateSalt() {
    $salt = '';
    $length = rand(5,10); // длина соли (от 5 до 10 сомволов)
    for($i=0; $i<$length; $i++) {
         $salt .= chr(rand(33,126)); // символ из ASCII-table
    }
    return $salt;
}

Различные варианты соления в известных движках:

  • md5($pass.$salt) — применяется в Joomla
  • md5(md5($pass).$salt) — применяется в vBulletin
  • md5(md5($salt).md5($pass)) — применяется в новых IP.Board
#1

Отличный прием, некое подобие связки открытый-закрытый ключ. Пользуюсь.

Дмитрий, 19.03.2009 - 23:11
#2

Спасибо большое, из статьи понял как в принципе хранить пароли, и согласен, что третий способ лучше... буду его использовать. Спасибо большое... осталось только узнать по какому принципу работает md5(просто интерестно...). Буду теперь заглядывать к Вам почаще...

Евгений, 29.07.2009 - 21:05
#3

А ничего страшного что salt у нас хранится в открытом виде в БД?

Александр, 30.09.2009 - 12:15
#4

используя алгоритмы шифрования md5, sha1 и т.д. - это собственно хэши, а не алгоритмы шифрования. самый лучший хэш на сегодня sha1, но в случае хранения паролей и md5 достаточно (оно же известно как crc32).

developer, 2.10.2009 - 01:35
#5

>и md5 достаточно (оно же известно как crc32).

Точно? А ничего, что CRC32 32 битный и является алгоритмом подсчета контрольной суммы, а md5 128 битный алгоритм хеширования? =)

ToNik, 10.11.2009 - 14:28
#6

Спасибо! Интересный прием.

Martiner, 6.12.2009 - 22:02
#7

Я использую такой метод: хешируем пароль, тримим от него несколько символов (с начала\с конца) и еще раз хешируем. Не нужно возиться с записью\получением соли.
Хотелось бы услышать мнение автора на этот счет.

vo.one, 10.02.2010 - 16:24
#8

to #7:
ну то что вы тримите какие то символы (с начала\с конца) - это уже и есть своеобразная соль =) А потом все это полученное сново хэшируете. Соль можно по-разному добывать )))))))

djken, 29.05.2010 - 02:13
#9

3-й способ хранения паролей конечно хорош =) Но меня вот только один вопрос интересует: вдруг пользователь забыл пароль и хочет его восстановить, например, через Email - как в таком случае быть, если пороли в БД не хранятся в явном виде???

djken, 29.05.2010 - 02:18
#10

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

ZooLoo, 1.06.2010 - 14:56
#11

А как вы считаете, что лучше пересылаеть на сервер и хранить в куках/сессии - незашифрованный пароль? Или, например, результат первого/второго хэширования? :)
Я просто смотрел, что мне некоторые сайты кладут в куки и там иногда лежало что-то уж совсем на мой пароль непохожее.

Aminon, 6.07.2010 - 10:51
#12

В куках лучше вообще ничего не хранить кроме id сессии. Все пользовательские данные лучше хранить в сессии (глобальный массив $_SESSION). В Контакте хранил пароли в куках md5(пароль) - самое папулярное шифрование паролей на сайтах. С первого взгляда пароль вроде шифрован, но на самом деле каждый второй взламывается http://ekimoff.ru/241/

Еще раз, не храните личные данные в куках.

admin, 6.07.2010 - 11:01
#13

Cессия долго не живет, а заставлять человека каждый день заново входить - это садизм.

Aminon, 6.07.2010 - 16:23
#14

to #13
просто ставьте id в куку со сроком жизни 1 год

Хость, 25.07.2010 - 19:37
#15

А ведь правда, если вы хотите защититься от взлома в случае получения взломщиком доступа к базе, то почему оставляете соль в открытом виде возле пароля? Это можно понять только если используется какой-то хитрый алгоритм ее взаимодействия с паролем, но в статье приведены только самые простые примеры.

yefrem, 29.07.2010 - 23:16
#16

to #15
Знание соли никак не поможет расшифровать хеш.
Без соли проблема в том, что все не слишком длинные пароли уже прохешированы (gdataonline.com). С солью последнему хешированию подвергается довольно специфичная уже запись, которую так уже не найти (ибо их не триллионы, а числа, на несколько порядков выше))

Cthulhu, 2.08.2010 - 18:09
#17

мда... соль это канечно интересно но вот беда открытое хранение этой самой соли. Ну да сложнее подобрать и так далее... но не забывайте что в данном случае будут иметь место коллизии алгоритма хеширования. Я предлагаю и сам уже давно пользуюсь следующий метод... задается жесткая длинна пароля скажем в 52 символа... а вводить разрешается только 20 затем те символы что ввел юзер стокаются до тех пор пока не достигнута длинна пароля в 52 символа... прогоняем через любой алгоритм хеширования и вуаля... как вы думаете на сколько велика вероятность коллизии в данном случае? вот такой механизм соления на порядок безопаснее вашего... тоже самое касается и алгоритма представленного в седьмом посте.

dseroot, 28.09.2010 - 10:19
#18

to #17

"как вы думаете на сколько велика вероятность коллизии в данном случае?"

Ровно такая же, как и без ваших "стоканий". Вероятность коллизий уменьшается только при увеличении длины хэша, а длина самого пароля ей полностью пофиг, т.к. теоретически в один и тот же хэш может сложиться и фраза в 1 символ, и фраза в 255 символов.

Aminon, 20.10.2010 - 16:30
#19

to #14
"просто ставьте id в куку со сроком жизни 1 год"

Ну да, и хранить на сервере все сессии за год, отлично придумано :) К тому же, я не вижу абсолютно никакой разницы, хранить в куках хэшированный пароль или id сессии - при краже кук любой вариант позволит зайти на сайт.

Голый пароль в куках хранить опасно, да. Но между id сессии и хэшированным паролем разницы не вижу.

Aminon, 20.10.2010 - 16:36
#20

А если так?
md5(md5($pass).sha($pass))

Тогда и соль хранить не надо....

Николай, 1.11.2010 - 12:45
#21

to # 19

не любой.
привяжи id сесии к ip адресу клиента который будет заходить
id будет регениться рандомно каждый раз при новой сесии а привязка будет на время сесии до выхода пользователя
тогда не будет разницы динамический ip или статический,и все буду счастливы )

Анна, 3.11.2010 - 19:35
#22

Спасибо! Очень много полезного узнал, а то уже устал думать о защите. Прекрасный вариант с сессией которая привязана к айпи!!! Самому сразу в голову не пришло из-за размытости общей картины. =)

Спасибо, 17.11.2010 - 01:34
#23

Спасибо, помогло) все очень доступно написано)

'md5("privet") ', 19.03.2011 - 14:09
#24

Добавлять по очереди то соль, то воду, то ещё чего, можно до бесконечности... Не вижу смысла.
Первая проблема - это, короткий, "не извращённый" (и часто состоящий только из цифр) пароль пользователя. Взлом заключается в сравнении украденного хеша и хеша из "радужной таблицы". Размеры таблицы - не бесконечны. Скажем при переборе всех паролей из 6 символов (т. е. перепробовав все возможные символы в таком пароле, например 0-9, a-z, A-Z, всего 62 символа) получаем 62^6 (62 символа в 6-ой степени) = 56'800'235'584 хешей. Каждый длиной 32 байта, значит места на диске для хранения таблицы нужно 56'800'235'584 * 32 = 1'817'607'538'688 т. е. примерно 2 Тбайта. Это не очень много , но и пароль у нас был длиной всего в 6 символов, и именно такие короткие пароли (ну или чуть длиннее 9 -12 символов, но тогда генерируются и хранятся хеши паролей по словарю, т. е. по списку чаще используемых узерами паролей, это обычные слова, цифры ну и т. д., т. е. не "извращённые" пароли) . А теперь посчитайте сколько хешей будет при длине пароля в 32 символа. Но заставлять узера вводить и помнить пароль из 32-ух символов, конечно же не реально, поэтому просто-напросто прогоняем реальный пароль узера 2 раза, например функцией md5();. После первого прогона мы получаем пароль, при чём не простой, а "извращённый", и длиной в 32 байта. А при втором прогоне, уже пароля из 32-х символов, получаем новый хеш, который и сохраняем. Теперь, что бы путём перебора определить из имеющегося хеша предыдущий хещ, а за тем по найденому предыдущему хешу - реальный пароль узера, нужна будет, мягко говоря, "бесконечная" таблица хешей..................
Вот так, примерно!

Но это всё была присказка!!! а сказка - впереди...

Теперь возвращаемся к нашей главной проблеме, КОРОТКИЕ И ПРОСТЫЕ ПАРОЛИ узеров.

Что мне нужно, что бы "взломать" выше описанный способ "хренения" паролей. А главное - что я уже ИМЕЮ для этого?
А имею я совсем НЕ МАЛО! Можно сказать, что у меня уже есть пароль узера!!! А точнее говоря - у меня уже есть все пароли большинства узеров!!! А почему? да всё потому же! "короткие и простые пароли узеров".

Теперь, что я делаю...
1. Я регюсь на взламываемом сайте.
2. Взламываю БД или то место, где хранятся хеши паролей. (это условие данной темы)
3. Нахожу свой хеш. (по моему имени узера)

-. Зачем мне нужны первые три шага?
+. Для того, чтобы определить, каким образом получают хещ на сайте. Т. е. я перебираю возможные варианты:
md5($pass);
md5(md5($pass));
md5(md5(md5($pass)));
sha1(md5(crypt($pass)));
... и т. д., пока не получу мой хеш!
Если программер использовал просто md5(md5($pass));, то мне легче.

4. "Формула" получения хеша у меня есть, теперь мне нужна прога которая сгенерирует
все хеши ПО ДАННОЙ формуле (скачаю или сам напишу), и не много времени (если в секунду 1'000'000 хешей, то для 56'800'235'584 хешей это около 20 часов, НО это считайте МАКСИМУМ, а если по словарю перебирать или только пароли из цифр, то времени на порядок меньше потребуется).
И ВСЁ! Все пароли длиной до 6-и символов у меня "в кармане"!

И так! Этот метод взломали, теперь ПРО СОЛЬ...

Ломаем метод автора статьи...

-. Выполняю первые 3 шага.

Теперь, если я взломал БД и получил хеши паролей, то я также и получил каждую "солинку"!!!

И что я делаю???
Да всё тоже самое!!!

Просто теперь при поиске "формулы" получения хеша я добавляю эту соль, при чём всеми возможными вариантами!

md5(md5($pass.$salt));
md5(md5($pass).$salt);
md5(sha1($salt.crypt($pass)));
... и т. д..
Ну а далее думаю уже догадываетесь... Генерю все хеши добавляя соль УЖЕ в правильное место и используя правильную формулу.

НО здесь как видите уже есть один "худенький" плюсик.
Речь уже идёт не о взломе всех паролей, а о взломе одиночного аккаутна, соль то для каждого узера своя, а значит генерировать таблицу придётся для каждого узера заного. Во как!
А почему плюсик "худенький"???
Да опять же всё потому, что "ПРОСТЫЕ И КОРОТКИЕ ПАРОЛИ"!!! (на верное я вам уже надоел?!... терпи'те!)

Начинаю генерить по словарю используя только цифры (большинство паролей - это даты рождения). Обычно на сайте требуют пароль длиной не менее 6-и символов, т. е. я перебираю например:

даты типа 010101; (длина 6 символов, всего их от 01 января 1901 года, до 22 апреля 2011 где то 365*110=36500 !!! ВСЕГО ТО ?!! и это я ещё щедрый, а можно смело убрать первые лет 50 и последнии лет 10-15.

Так же, даты когда узер пишет что то типа 111977; (1 января 1977 года, т. е. варианты без нулей)

Так же варианты с 7-и значными датами и с 8-и значными...

"Год у меня был... 3 - за побег... 5 - за дет-сад... ну сколько за старуха дадут? ну пусть 10 лет... И я из-за каких-то 16 лет........................." =)))

Ну пусть у нас получилось всего 1'000'000 вариантов даты рождения! Если машина генерирует 1'000'000 хешей в секунду - получается я буду вскрывать по узеру в секунду, а если двигаться от младших к старшим, то ещё быстрее!!!

И что у нас получилось? Мы вскрыли за один час - 3600 узеров "с СОЛЬЮ"!!!!!!!!

И вся прелесть в том, что и соль НЕ ПОМОГЛА! А почему??? Вижу по лицу, уже догадались. =)))
последний раз: "ПРОСТЫЕ И КОРОТКИЕ ПАРОЛИ"!!!

"И что же?" - скажете вы - "значит нет надёжного метода???".

И ПРАВИЛЬНО скажете!

Вы ищете в интернете надёжный метод или как вы ещё любите "часто используемый метод", и при этом вы УЖЕ СОВЕРШАЕТЕ ОШИБКУ! потому, как "то, что знают двое - знают все!" и как вы знаете "то, что один человек построил - другой завсегда поломать сможет".

Ну так и что же делать???

А всё просто, "ХОЧЕШЬ ЖИТЬ - УМЕЙ ВЕРТЕТЬСЯ!"

Не используйте общеизвестные приёмы, или изменяйте их на свой манер, отпиливайте, приклеивайте, меняйте местами, копируйте, придумывайте что то своё, и т. д. и т. п.. Думайте своей головой. И вообще, подумайте, а стоит ли овчина выделки?!! Нужна ли вам эта бетонная крепость, или можно и и так прожить в деревянной... Даже если вы напишете код, который будет чередовать функции хеширования 10-20 раз, например в файле "enter.php". Во первых: что мне помешает написать программку которая будет перебирать все варианты чередования функций md5, sha1, crypt, и т.д., и в итоге будет находить нужную последовательность за считанные секунды. А во вторых: где гарантия, что я не заставлю сервер не выполнить ваш файл "enter.php", а просто прочитать его, или найти в вашем сайте ещё какую дырку и получить исходный код файла. И тогда хоть ваш код чередует 1000 раз, да и всё что угодно, я просто повторю ваш код при генерации таблицы хешей и результат будет тот же, а все ваши старания понапрасну... =(((

Так что, надёжной защиты нет. Бывает лишь более надёжная защита, и бывает хакер который хитрее Вас, кстати, который не обязательно умнее Вас!

//====================================================

k313, 22.04.2011 - 03:27
#25

Ну причем здесь брутфорс?! Человек пишет про защиту паролей от взлома посредством "Радужных таблиц". Которые нужны для взлома там, где брутфорс не помогает, т.е., на относительно сложных паролях. А то, что так длинно описывается в предыдущем комменте, можно сформулировать двумя тезисами:
1) простой пароль проще всего ломать перебором;
2 секртеность не дложна обеспечиваться сокрытием алгоритма шифрования.
По-моему, оба тезиса всем, кто занимается данным вопросом, давно известны.

K314, 4.05.2011 - 08:58
#26

"Не используйте общеизвестные приёмы, или изменяйте их на свой манер, отпиливайте, приклеивайте, меняйте местами, копируйте, придумывайте что то своё, и т. д. и т. п.. Думайте своей головой."
Правильно.

"где гарантия, что я не заставлю сервер не выполнить ваш файл "enter.php", а просто прочитать его"
Вот от этого как защититься? Ведь в таком случае вообще ничто не поможет.

Дмитрий, 23.07.2011 - 14:53
#27

«А теперь посчитайте сколько хешей будет при длине пароля в 32 символа. Но заставлять узера вводить и помнить пароль из 32-ух символов, конечно же не реально, поэтому просто-напросто прогоняем реальный пароль узера 2 раза, например функцией md5();. После первого прогона мы получаем пароль, при чём не простой, а "извращённый", и длиной в 32 байта.»

бред. от того, что вы прогнали 6 символьный пароль через тот же md5, его длина не станет 32 байта.
если вы знаете, что в базе хранится хэш вида md5(md5(pass)), то ваш перебор абсолютно аналогичен перебору md5(pass)

«Не используйте общеизвестные приёмы, или изменяйте их на свой манер, отпиливайте, приклеивайте, меняйте местами, копируйте, придумывайте что то своё, и т. д. и т. п.. Думайте своей головой.»
эта фраза подтвердила первоначальное мнение о вашей компетентности в обсуждаемом вопросе.

Евгений, 16.08.2011 - 16:46
#28

Я же сказал - не вижу смысла.
Первый абзац - это пересказ замысла автора данной статьи, так, для вступления.
----------------------------------------------------------
| 3 способ. Храним пароль в зашифрованном виде, но
| добавляя несколько случайных символов, уникальных для
| каждого пользователя (так называемая соль). А еще лучше
| хранить двойной md5 с солью. Взломать такой
| вышеупомянутым способом практически невозможно."
---------------------------------------------------------

k313, 19.08.2011 - 03:33
#29

А на счёт
********************************************************
"где гарантия, что я не заставлю сервер не выполнить ваш файл "enter.php", а просто прочитать его"
********************************************************
- если вы не администратор сервера, то вам об этом думать и не надо. Это уже дырка в интерпретаторе, или в Apache, или в Linuxe, или ещё где... Сказано лищь для того чтоб вы не рассчитывали на 100%-ю гарантию даже если ваш код идеален... или на оборот, если к вам на сайт кто-то не санкционированно влез, чтоб вы не думали только о том что у вас гдето в коде дырка....

k313, 19.08.2011 - 03:49
#30

Ну и про хеш md5()

как извесно - его длина 128 бит...
то есть любой пароль длинее 16-байт непременно должен совпасть с одним из своих "младших братиев" (по хешу).
и нет гарантии что ваш супер-бупер-навороченный пароль не делит один и тот же хеш с паролем типа "123456"

Поэтому лучше использовать sha1()

k313, 19.08.2011 - 04:11
#31

Хороший метод, сам им пользуюсь, вот только соль в СУБД не храню, а просто существует в скрипте в качестве константы и при необходимости прибавляется скажем к паролю пользователя и только потом шифруется md5, таким образом если украсьть из базы пароли и расшифровать то получаются совсем другие

Дмитрий, 10.09.2011 - 13:29
#32

Можно откомпилировать скрипт в бинарник, который генерит пароль по определенному (своему собственному) алгоритму - это будет черным ящиком, даже если его сольют с сервака, то долго будут трассировать его дебагером, если бинарник после компиляции еще и зашифровать ;)

noname, 7.11.2011 - 20:34
#33

Я так понял,что собрались здесь в основном системные администраторы...т.е. люди ответственные в той или иной степени за сохранность паролей простых смертных как я. Объясните мне человеку не очень сведущему во всём этом.Если мой пароль будет состоять скажем из как минимум двадцати знаков(цифры,латинские буквы в разном регистре,спецсимволы и т.д.-пароль скомпилирован прогой KeePass и хранится в ней же) такой пароль методом брут форса т.е. подбора будет взломать сложно,я правильно понял? Насколько такой такой пароль будет трудно сломать если его хеш будет перехвачен,украден на сайте,на котором я его постоянно ввожу(копипастом-не руками)?
Я все пароли к почтовым ящикам,аське,вэб мани,пай палу,скайпу и прочей билибердени храню в этой проге...все пароли очень сложные,случайные(покрайней мере так утверждается разработчиками проги) и сугубо индивидуальны(нет ни одного одинакового пароля).Сами базы хранятся не на компе,а на флэшке, на зашифрованном разделе(прога TrueCrypt).Насколько защищена моя инфа(пароли),если злоумышленник перехватит хеш пароля(сорри за повтор)?
ps скажите пожалуйста,я в качестве пароля к зашифрованному разделу и к базам паролей использую хеш файлов...те просто копирую мд5 файла лежащего на компе в строку ввода пароля. Это безопасно? Такой пароль сломать легко или сложно.А то может в нем есть какая нибудь система которую прога для взлома на раз два расколет,а я этого не знаю.

desadro, 10.01.2012 - 21:12
#34

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

admin, 11.01.2012 - 08:39
#35

#33,
Ну ты просто монстр конспирации :)))
С таким подходом к безопасности, конечно, у потенциальных злоумышленников мало шансов против тебя, но. Но существует ряд проблем с такой организацией безопасности. Например, ты говоришь, что в качестве "мастер-пароля" используешь MD5 хэш файла, хранящегося на твоём компе... Я надеюсь, что содержимое этого файла ты знаешь наизусть и сможешь легко воспроизвести при необходимости? Потому что при потере лишь одного этого файла (выход из строя жёсткого диска, вирусы, ошибка в работе произвольной программы, случайное удаление - "человеческий фактор") и ты моментально теряешь доступ ко всем своим паролям на флэшке.
А в остальном - да, такой подход - это максимум, что ты можешь сделать для своей безопасности как обычный пользователь.
И не забывай про резервное копирование: флэшки тоже имеют свой ограниченный срок службы. В среднем 10-20 лет, но никто не застрахован от форс-мажоров (к тому же существует возможность её банально потерять, уронить, утопить и т.д.).

asd, 29.01.2012 - 23:11
#36

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

Обычному программисту, пусть даже и с большим опытом, не будучи экспертом в области криптологии, будет довольно сложно оценить криптоустойчивость произвольного алгоритма. Зато не составит никакого труда придумать максимально запутанный алгоритм хэширования.
Просто пример того, что я имею ввиду:
1. получаем самый обычный хэш из пользовательского пароля;
2. читаем N первых символов из полученного хэша ("соль");
3. генерируем новый хэш из строки "оригинальный хэш" + "соль";
4. читаем N-ый байт из полученного хэша (в случае с MD5 - это даст нам шестнадцатиричное число, т.е. число от 0 до 15);
5. прогоняем хэш, полученный в пункте 3 через алгоритм хэширования столько раз (md5(md5(md5(...)))), сколько указывает число, полученное в пункте 4;
6. ;
7. .

В итоге, вы получаете пусть и не самый устойчивый к взломам алгоритм (хотя далеко не факт), но! Устойчивость его заключается в скрытости алгоритма. Взломать хэш можно только подбором, других алгоритмов пока не существует. А подобрать коллизию можно только зная алгоритм. И если такой алгоритм, как md5(md5()) распознать довольно легко - то алгоритм, который я привёл в качестве примера, распознать будет уже НУ ОЧЕНЬ непросто (а если честно, то я считаю, что и вовсе невозможно).

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

Хотя, надо отдать должное такому подходу - даже получив исходный код реализации "секретного алгоритма", при достаточной его сложности, злоумышленнику всё равно придётся потратить много времени на то, чтобы "развернуть" этот алгоритм в обратную сторону.

В добавок, если этот алгоритм будет достаточно трудоёмким - скажем, не 5-7 шагов, как в примере выше, а 1000-10000 (даже если это будет просто md5(md5(...)) и так тысячу раз) - то злоумышленнику потребуется, соответственно, в 1000 или 10000 раз больше времени для подбора пароля (потому что генерация одного хэша в такой схеме элементарно занимает в 1000 раз больше времени).

asd, 29.01.2012 - 23:46
#37

To #36
"System security should not depend on the secrecy of the implementation or its components."
http://bit.ly/1crEZqs

Io, 7.06.2012 - 22:35
#38

Проблема обычных хешей в том что они очень, очень быстро брутфорсятся. Они для этого и сделаны.

Пароль надо шифровать медленной криптохеш-функцией.

Подробнее здесь:

http://codahale.com/how-to-safely-store-a-password/

varnav, 4.07.2012 - 20:41
#39

Вы тут рассуждаете об алгоритмах, соли... а ничего что у вас пароль по сети в открытом виде передается?
Ну и не могу сдержаться, чтобы не прокомментировать, что двойной хеш "md5 (md5 (pass))" намного труднее взломать.. это написано, видимо, от больших мозгов. Для поиска исходной строки от второго md5() у нас есть уже все данные: известен словарь - всего 16 (!) символов (0-9, a-f), известна длина слова - 32 символа, и кто то будет утверждать, что по этим данным сложно найти хеш от первого md5()?

Vital, 18.09.2012 - 16:03
#40

я делаю так:
sha1( $this->salt . '' . md5( $this->secretKey . '' . $this->password ) )

при этом в БД secretkey не хранится, только в конфиге сайта.

по моему самый оптимальный вариант.

larein, 19.09.2012 - 20:26
#41

Дочитал до конца статью и все комментарии.
Информация в статье не новая и с учётом достаточной (в данный момент) популярности этого алгоритма - "соление" не сильно усложняет жизнь взломщику БД.

Больше всего я оценил 36-ой пост комментариев (asd, 29.01.2012 - 23:46 ).
Данный товарищ говорит всё правильно.
Взломщику БАЗЫ ДАННЫХ (а не сервера с исходниками, например, php-скриптов) более чем трудно (не хочу эпатировать публику громкими заявлениями о НЕВОЗМОЖНОСТИ) будет определить способ НЕСТАНДАРТНОГО шифрования, ПРИМЕР которого был приведен выше в 36-ом посте комментариев.

По поводу "System security should not depend on the secrecy of the implementation or its components.":
не поленитесь прочитать в контексте чего используется данное утверждение, т.е. к обсуждению на этой странице это неприменимо.

aadktnbaov, 18.10.2012 - 14:16
#42

Доброго времени суток всей честной кампании.
Присоединяюсь к высказываниям о бесполезности создания алгоритмов защищающих хеши пользователей при доступе к исходному коду.
Для себя решил, что не буду использовать хеширование, как матрешку, нагромождая функции друг на друга.
На мой взгляд, наиболее выгодно генерировать уникальную соль для каждого пользователя используя определенный алгоритм, опирающийся на его же (пользователя) информацию.
На пример, можно смешивать хеш пароля, символы имени пользователя или добавлять числовой код символов используя тот же ord(). Необходимо лишь использовать информацию, которая гарантировано не изменится. В этом случае электронный адрес уже не подойдет.

Или еще вариант: хешируем (не важно как и чем) пароль пользователя. Читаем по символьно хеш и имя пользователя. Находим числовой код определенного символа имени пользователя и определенный символ хеша с помощью ord(). С помощью определенных математических операций получаем числовой код нового символа для chr(). И т.д.

Другими словами, на мой взгляд, создать достаточно сложный механизм генерации соли/хеша не так уж и сложно. Намного сложнее, чем определить каким образом он генерируется. Самое главное использовать свои алгоритмы и быть оригинальным. Никто же не кладет ключ от квартиры под коврик... Или?!

XelaNimed, 2.11.2012 - 03:31
#43

А серьезно, чем плох вариант md5(md5(pass)) или например md5(md5(md5(md5(pass)))). как утверждает комментатор №39, у нас есть все данные - 16 вариантов, 32 знака.
16^32 >= 3.4*10^38 варианта. неплохо. заставил считать для примера пассворд про 38 знаков, говорит, больше 10 тыс дней буду считать. это просто максимальное значение. посчитаем сами. ну если средняя скорость 4,6 млн вариантов в секунду, то получится 2,3*10^24 лет. очень неплохо! и это мы проделали только одну операцию по брутфорсу хэша md5(md5). соответственно, если несколько последовательных операций, то и умножать надо эти многогоды на 2 или 4 или сколько таких операций (что в общем то уже не существенно, т.к. порядки разные. последнюю операцию, md5(pass), будет подобрать уже быстрее, и намного, ибо знаков там меньше, 6 знаков - 6:30 мин, 7 знаков - 4 с лишним часа, 8 знаков > 6 дней ну и так далее. согласен с номером №24, про простые пароли, сам не проверял, но уверен, что в радужных таблицах давно есть хэши от хэшей от хэшей и тд для простых, распространенных паролей. а от нормального "псевдослучайного" пароля таблицы нету, но запоминать, (а еще и каждый раз вводить) многоцифер тоже не хочется. соответственно конструкция md5(md5(pass)) позволяет и рыбку съесть, и, ну вы понели.. если я в чем не прав, поправьте, буду благодарен

rom.ich, 29.11.2012 - 23:03
#44

Всем доброго времени суток. В комментариях опять наткнулся на идею использовать такой вариант md5(md5(md5(md5(pass)))), только с гораздо большим количеством операций хеширования. Такой вариант может быть эффективен только в том случае, если гарантировано, что хеширование не даст коллизий. Тот же md5 дает коллизии, что пагубно сказывается на таком алгоритме. Если у вас хеширование вложено 1000 раз, то достаточно найти "псевдо-пароль", который даст хеширование которого даст коллизию всего в одном из 1000 раз. Это гораздо проще.

Александр, 9.07.2013 - 19:56
#45

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

Илья, 8.07.2014 - 09:46
#46

Искала соль, а нашла Соль благодарю кул информация!

Юлия Касева, 29.12.2014 - 22:03
#47

Зачастую имя уже известно(ведь его надо показать в приветствии), значит оно как соль не подходит. Пароль + соль не очень эффективный метод, найти коллизию в целом хеше не сложно. В интернете полно готовых решений. Однако существует панацея и от коллизий. 1) Если это простой пароль в базе данных который проверяется путём сравнения значений. То самое простое "обрезок готового хеша пароля" + "обрезок готового хеша соли". Например: логин([2804e0bda79bd8b5]016878442b110b95), пароль(749789e4982b0c56[3f6729aac100a614]) = [2804e0bda79bd8b5+3f6729aac100a614] Конечно, этому хешу тоже принадлежат значения однако имея на руках только пол хеша никогда не узнать его истенного значения! Выглядеть будет как обычный 32 символьный хеш. 2) Если необходимо в будущем дешифровать данные можно предложить следующее решение(хочу сразу заметить этот способ в разы усложняет поиск коллизий, так как перед этим придется расставить символы по местам): помимо пароля нужны 2 поля для ввода чисел. Готовый хеш(32 символа) разбивается на блоки из 1-го поля - 2,4,8,16,32; второе число будет соответствовать, заранее определенному, порядку перемешивания. Однако стоит отметить что таким способом лучше шифровать отдельные слова. Иначе впоследствии могут возникнуть проблемы с дешефрацией. Если я в чемто ошибся поправьте меня!

alekseicrysis, 24.01.2016 - 15:29
Оставить комментарий