Насколько безопасно хранить пароли в md5?
138 сообщений
#15 лет назад
Здраствуйте. Сегодня сделал шифр паролей в админку md5(md5($pass)).Скажите насколько безопасно? или есть вариант получше?
16382 сообщения
#15 лет назад
Не думаю, что стойкость самого md5 послужит самой большой дырой в безопасности. А если и послужит, то эта самая большая дыра будет совсем незначительна. Можно и безопаснее, поизгаляться... и хэши есть не только md5 и к самому паролю можно подмешивать данные, но все это, имхо, для гурманов. На практике пароль будет проще заменить, чем восстанавливать его из вашего хэша.
138 сообщений
#15 лет назад
Цитата:На практике пароль будет проще заменить, чем восстанавливать его из вашего хэша.
Я имел виду если ктото брутом будет пытатся попасть в админку.
P.s а вот такой способ видел md5(md5($pass).md5($salt)) ... переменая pass понятно откуда... а переменая salt ? или туда можно подставить любое свое значение?
3240 сообщений
#15 лет назад
Цитата ("kiril1989"):Здраствуйте. Сегодня сделал шифр паролей в админку md5(md5($pass)).
Скажите насколько безопасно? или есть вариант получше?
Слово "хранить пароли" тут не подходит, так как MD5 — хеш функция, и кодирование будет необратимым.
Кстати, именно поэтому использовать MD5 кодирования пароля вполне приемлемо и безопасно.
Если алгоритм кодирования известен взломщику, то с точки зрения безопасности, в общем, нет разницы, как именно Вы применяете MD5.
То есть, md5($pass) и md5(md5($pass)) обеспечивают практически одинаковый уровень стойкости.
Почему?
Потому что при использовании хеш функций для кодирования есть только один способ определить исходный пароль — подбор, обычно по словарю.
И с точки зрения безопасности не так важно, один ли раз вызывать md5($pass), или десять раз... Pазве что дольше подбор будет производиться, то есть единственным (но спорным, и не во всех случаях подходящим) преимуществом усложнения алгоритма кодирования может быть лишь увеличение времени на кодирование.
Если же алгоритм кодирования неизвестен, то взломщик тут беспомощен. Но это уже другая тема.
Кстати, в большом количестве платежных систем MD5, наряду с SHA1, HMAC и т.д., используется для пароля или подписи.
При этом к паролю или сообщению обычно добавляется секретный ключ, например так: md5($input . SECRET_KEY), что обеспечивает дополнительный уровень защиты.
11416 сообщений
#15 лет назад
Если у вас пароль достаточно простой, то имея md5 расшифровать элементарно... Лучше всего добавлять к паролю какое-то значение, и только потом его уже в md5
PS. TVV, как всегда браво!

16382 сообщения
#15 лет назад
Цитата ("tvv"):один ли раз вызывать md5($pass), или десять раз... Pазве что дольше подбор будет производиться
в том и суть. если хэширование будет происходить очень быстро, на подбор потратится много меньше времени и тогда брутфорс будет оправдан. А вот если кодирование продолжительно по времени - тут уже сильно не поперебираешь. Так что усложнять смысл есть.
Цитата ("kiril1989"):
переменая pass понятно откуда... а переменая salt ? или туда можно подставить любое свое значение?
любое неизвестное тому, кто будет подбирать.
1594 сообщения
#15 лет назад
Кстати, вычитал, что удобно в качестве "соли" или разделителя ( в конструкциях md5($pass.разделитель.$salt) использовать последовательности вида "\n" или "\r", т.к многие брутфорсы (PasswordPro, например) их не поддерживают
3240 сообщений
#15 лет назад
Цитата ("frig"):в том и суть. если хэширование будет происходить очень быстро, на подбор потратится много меньше времени и тогда брутфорс будет оправдан. А вот если кодирование продолжительно по времени - тут уже сильно не поперебираешь. Так что усложнять смысл есть.
Да, я об этом и написал в своем сообщении.
Но тут уже нужно смотреть на природу данных.
Если заставлять пользователей создавать длинные криптостойкие пароли, то однократного MD5 вполне достаточно (но я лично не рекомендую).
Так как даже если в разы ускорить кодирование, все равно подбор пароля займет десятки лет.
Впрочем, даже если и короткий пароль, то md5($input . SECRET_KEY) с длинным SECRET_KEY (солью) решит проблему, включая брутфорс с использованием Rainbow table.
Именно этот способ и является на данный момент рекомендуемым.
Вот если среди паролей возможны типа "qwerty", "123", и т.д., и не хотите использовать SECRET_KEY, вот тогда да, алгоритм нужно усложнять, так как все такие простые пароли уже давно в словарях брутфорсеров и на md5($pass), и на md5(md5($pass)) и т.д. Но это тупиковый путь в принципе.
4 сообщения
#15 лет назад
Я в последнее время немного иначе храню пароли, но способ подходит только для своего сервера.В общем написал shell-скрипт для кодирования blowfish'ем, в нем же валяется ключ.
ПХП работает в safemode, этот скрипт валяется в папке с разрешенными для выполнения (safe_mode_exec_dir), но за пределами видимости по ftp.
Потом вызываю просто через passthru свой криптер. Таким образом, получив доступ к ftp, БД ты все равно ничего не сделаешь, ключа не знаешь, не сможешь заменить хеш, также ты его не знаешь, не сможешь расшифровать пасс. Вариант получается только менять сырки, с тем чтобы миновать авторизацию. Однако, тут тоже косяк, все зазендено последней версией ZendEncodera, получить исходники будет трудно

Думаю, способ довольно-таки надежный.
3240 сообщений
#15 лет назад
Цитата ("frig"):Цитата (kiril1989):
переменая pass понятно откуда... а переменая salt ? или туда можно подставить любое свое значение?
любое неизвестное тому, кто будет подбирать.
Немного не так. То, что Вы написали, про неизвестное — это Secret Key. Хотя, конечно, и нет гарантии что этот Secret Key не станет известен брутфорсеру, но значительно повысит безопасность.
Я об этом написал выше.
Соль (salt) же — это нечто другое.
Прежде всего, использование соли защищает от того, чтобы быстро определять пользователей с одинаковыми паролями в списке паролей.
Далее, существуют различные методики подбора паролей, например, я упоминал Rainbow table. Так вот, соль предназначена для защиты от таких методик.
Это очень помогает, когда к брутфорсерам попал не один хеш, а целый список или база данных хешей, таким образом им придется подбирать каждый пароль в отдельности, а не все одним махом.
Использование соли похоже на Secret Key, вот пример использования: $hash = SALT . md5($pass . SALT);
Но отличие в том, что SALT обычно не скрывают, а каждый раз вычисляют налету, это случайная комбинация определенной длины, и ее добавляют прямо к закриптованному паролю в открытом виде (этого достаточно для того, чтобы соль выполнила свое назначение).
3240 сообщений
#15 лет назад
Немного теории, как обеспечить безопасную работу пользователей, если в системе используются пароли:1. Заставлять пользователей вводить только длинные криптостойкие пароли. Такие пароли очень долго и сложно подбирать.
2. Устанавливать срок действия пароля. Например, 1 месяц, или 6 месяцев, и т.д., то есть, установить такую политику. Даже если пароль пользователя будут подбирать, то это займет очень много времени, и большая вероятность, что, пока пароль подберут, он давно проэкспарится, и пользователь его сменит.
3. Если пользователь меняет пароль, не давать ему вводить такой же пароль, какой он вводил в этой системе когда-либо ранее (сохранять все старые хеши).
4. В базе данных пароль не хранить, а хранить результат хеш функции, с солью. Пример: $hash = SALT . md5($input . SECRET_KEY . SALT);
4.1. В этом случае SECRET_KEY — это секретный ключ, который никому нельзя показывать. Но, если злоумышленники и получили к нему доступ, то хоть это и не слишком критично, но может быть поводом порекомендовать всем пользователям сменить пароли (новые пароли будут с новым SECRET_KEY).
4.2. SALT — случайным образом сгенерированная комбинация определенной длины. Как я и писал в предыдущем сообщении, предназначенная для усложнения подбора паролей тем, кто получил доступ к списку хешей паролей всех пользователей.
4.3. $input — это может быть просто пароль, но желательно немного усложнить алгоритм (приняв меры, чтобы его не разобрали брутфорсеры, по крайней мере усложнив им жизнь... например в случае PHP это может быть оформлено в виде PHP расширения, написанного на Си), сделав его специфичным для проекта. Например это может быть $input = f($pass); — этот как раз в тему про md5(md5($pass)). В случае сверхповышенных требований к безопасности, можно сильно усложнить алгоритм, чтобы он выполнялся значительное время (например, около секунды на современном железе должно быть на данный момент достаточно), но тут нужно смотреть по задаче, например если пользователей сотни миллионов (например, проект класса gmail), то на это никакого процессорного времени не хватит.
Каждая из этих мер не является обязательной, но повышает безопасность системы.
16382 сообщения
#15 лет назад
tvv, меры правильные, но в большинстве случаев не применимы. Сильно страдает от этого удобство использования. Как от устойчивых паролей, так и от смены их по времени. Сильно раздражает пользователя, а это не есть хорошо. Т.е. далеко не всегда применимо это из соображений удобства использования.Самая большая дыра в этом деле, на мой взгляд, состоит не в хранении паролей, так как до самих хранимых паролей очень может быть что никто и не доберется, а в самой процедуре аутентификации и в самих паролях. Т.е. можно сделать очень и очень безопасным хранение пароля, но оставив возможность подбирать его прямо через форму логина (без ограничения попыток и интервалов между попытками) практически полностью все это дело подставляем под удар. Тоже самое касается и устойчивых паролей, но с ними сложнее, так как сильно напрягать пользователя плохо. ИМХО достаточно ввести ограничение на минимальную длину пароля в 5 символов, поставить таймаут после 2-х попыток входа в 10 секунд, а дальше по нарастающей +10 на каждую попытку, и можно на этот счет сильно не переживать - уже ничего особо подобрать не выйдет. Сам механизм хранения тут значения не имеет - будь он трижды устойчив этот хэш.
Если получат доступ к паролям, то значит получили доступ к базе, а значит не далеко от возможности вносить в нее изменения. Можно сменить сам хэш пароля, если там много намудрено и это не так просто, то можно сменить почту и восстановить пароль, там же и все вопросы и остальное при восстановлении. В общем если получили доступ к базе - уже можно не дергаться

зы сам использую связку sha1(md5()) и не парюсь на этот счет.
138 сообщений
#15 лет назад
tvv, Огромное спасибо... Ну это используется только для входа в админку... думаю админы которые будут использовать мой скрипт побезопасятся и небудут ставить пароли типа 123...Просто в прошлой версии скрипта пароли хранились вобще в открытом виде... вот я и подумал что ставить капчю или хеш паролей для того чтобы брутить пришлось долго и нудно...погуглив решил что md5 намного лучше капчи

Цитата:
можно сменить почту и восстановить пароль
Этой функции нет

3240 сообщений
#15 лет назад
Цитата ("frig"):Если получат доступ к паролям, то значит получили доступ к базе, а значит не далеко от возможности вносить в нее изменения. Можно сменить сам хэш пароля, если там много намудрено и это не так просто, то можно сменить почту и восстановить пароль, там же и все вопросы и остальное при восстановлении. В общем если получили доступ к базе - уже можно не дергаться .
Почему же не дергаться, тут можно, и даже нужно дергаться.
Во-первых, если увели БД, не факт что злоумышленники получили возможность вносить изменения именно в работающую систему.
С большой вероятностью увели бакап у хостера, или лишь скопировали на хосте физически файлы БД из-под другого пользователя.
Это самые частые случаи.
Далее, даже если у злоумышленников есть способ вносить изменения в БД...
Если при этом Вы спроектирвоали безопасное хранилище, то риски значительно снижаются.
Основных способа защиты от чужих рук в своей БД два: шифрование данных и подпись.
1. Шифрование используется для тех данных, которые не используются в поисковых запросах, и которые являются приватными. Алгоритм шифроваиня желательно реализовать в бинарном виде (усложнив существующие методы), и подключить в виде расширения. Но можно использовать и уже готовые. То есть данные при помещении их в БД шифруются. И если БД потом уведут, то увидят лишь зашифрованные данные. Или если будут налету менять что-то в БД, то уже не получится это делать вручную, придется очень сильно повозиться и понять логику алгоритма, что может быть крайне очень сложным делом (а если грамотно спроектирована система, и используется отдельный сервис авторизации и аутентификации, то все будет еще сложнее).
2. Подпись используется для тех данных, которые шифровать нельзя (например индексы, по которым производится быстрый поиск), или нет смысла, или по какой-то причине разработчики это не могут сделать. Вот например текущий пример:
Цитата ("kiril1989"):
есть 3 ячейки - логин,пароль,и права доступа(админ или модер)
Если "модер" получит доступ к БД, и она не зашифрована, он сможет легко сделать себя админом, лишь изменив вручную поле с правами доступа.
Чтобы этого не произошло, добавляется еще одно поле "подпись". Например, оно будет формироваться так:
$sign = md5($login . $encodedpass . $permission . SECRET_KEY), или можно использовать свой алгоритм, главное чтобы к нему было сложно получить доступ тому, кто увел базу или имеет к ней доступ.
Потом, если используется подпись, и если кто-то руками поменяет права доступа, то в следующий раз этот пользователь даже залогиниться не сможет, так как валидация не пройдет, ведь будет сравниваться не только логин и хеш пароля, но и проверяться подпись.
Но вообще, именно в данном случае больше бы подошло шифрование, но это другая тема.
Вообще тут много чего можно сделать, способов реализации масса как защититься от разных типов взломов — если БД увели, если к БД получили доступ, если к коду программы (исходникам) получили доступ, если могут снифить трафик между системой и базой, если могут вставлять жучка между системой и базой, и т.д. Все это уже давно изучено, и используется.
16382 сообщения
#15 лет назад
Цитата ("tvv"):Все это уже давно изучено, и используется.
Я в курсе ухищрений, но зачастую стоит вопрос в целесообразности применения того или иного решения. Мне сложно представить себе простой публичный проект с такими высокими требованиями к безопасности. Вопрос же обычно ставится как цена/качество. Качество в отрыве от цены мало чего значит. Все эти методы помогут повысить уровень безопасности, вопрос в том нужна ли она на таком уровне в таких проектах. Нужно ли изгаляться с шифрованием, подписями, сертификатами, ключами, требованиями к паролям, частотой их смены и так далее. Это все будет стоить дополнительных денег как на реализацию так и на поддержку, а ценность данных может быть много ниже всего этого, а значит ресурсы будут потрачены зря.
4 сообщения
#15 лет назад
Вот только лучше использовать не MD5, а SHA1 - длина хэша больше. А еще лучше SHA256. 
1594 сообщения
2989 сообщений
#15 лет назад
Есть простая, но довольно эффективная путалка:$password = $prefix.md5($pass).$postfix;
А еще эффективнее что-то вроде такого:
$password = base64_encode($prefix).md5($pass).base64_encode($postfix);
3240 сообщений
#15 лет назад
Цитата ("frig"):ИМХО достаточно ввести ограничение на минимальную длину пароля в 5 символов, поставить таймаут после 2-х попыток входа в 10 секунд, а дальше по нарастающей +10 на каждую попытку, и можно на этот счет сильно не переживать - уже ничего особо подобрать не выйдет. Сам механизм хранения тут значения не имеет - будь он трижды устойчив этот хэш.
Установить политику подобных ограничений — абсолютно правильно.
В случае веб сайта после нескольких неудачных попыток ввода пароля лучше даже не время увеличивать, а выводить каптчу.
Но что делать, если БД увели?
Если БД увели, получили хеш, и узнали Ваш метод хеширования, то 5 символов — явно недостаточно.
Например на моем стареньком ноуте 1000000 операций sha1(md5($pass)) выполняются за 2.5 сек, тест написал на PHP.
Это значит, что полный перебор 5-символьных паролей, состоящих из латинских букв в любом регистре и цифр займет 62^5 * 2.5 / 1000000 / 60 = 38 минут. Всего лишь.
Если бы был заинтересован, сделал бы на языке ассемблера, работало бы быстрее в несколько раз...
И это мне достаточно только один раз это вычислить и поместить в БД, в следующий раз не нужно будет делать полный перебор, а поиск пароля по предвычисленным значениям займет несколько секунд.
Для сравнения, если пароль будет лишь 8 символов, то перебор подобных же буквенно-цифровых паролей на этом же компе займет около 17 лет.
Я конечно понимаю, что можно использовать компы помощнее, да еще и в кластере... но все равно, разница ощутима.