Система пользователя и пароли: я просматривал материал MD5, и мне интересно, какая нормальная / хорошая практика для паролей. Прямо сейчас, я думаю, люди супер шифруют пароли и хранят хеши. Если да, то как работает проверка пароля? Я только что пароль ввода снова проходит процесс шифрования, а затем проверяет хэш с сохраненным, правильно?
Этот вопрос может противоречить вышеизложенному, но должна ли моя соль когда-либо быть случайно генерируемой ценностью? Если да, то когда это может быть полезно?
Изменить: кроме паролей, в пользовательской системе, что еще нужно зашифровать как хорошую практику? Записывают ли они имена пользователей или что-то еще?
2nd Edit: Что такое односторонний хеш? Я имею в виду, технически, могу ли я не перепроектировать мой исходный код? Возможно, это плохой вопрос, потому что я мало знаю об одностороннем хешировании.
Сначала вы создаете соль.
Примеры заметок написаны на PHP
// Setup a salt, this isn't "random" but it doesn't really have to be $salt = sha1(microtime());
Затем солить пароль
// First we hash the password, then XOR it with the salt hashing the result $hash = sha1(sha1($password) ^ $salt);
Храните $hash
и $salt
в базе данных.
Когда пользователь вводит пароль, сравните его с хэшем
if(sha1(sha1($entered_password) ^ $salt) == $hash) // Correct password
Никогда не храните пароли в обратимом формате. Также я бы посоветовал использовать MD5 как хэш.
Изменить: кроме паролей, в пользовательской системе, что еще нужно зашифровать как хорошую практику? Записывают ли они имена пользователей или что-то еще?
Пароли не шифруются, они хэшируются. Представьте хеш ( очень упрощенное) как нечто, которое принимает число и умножает его на десять. Скажем, я хочу хэш-номер 30
. Я бы сказал 30*10
и получил 300
как мой «хэш» за 30
. Обратите внимание: вы не можете получить 30
из 300
не зная, как работает хеш-функция.
Это очень упрощенная «хэш», и если вы знаете, что она всегда умножается на десять, тогда вы можете легко ее отменить. Теперь взгляните на хэш-функцию SHA1 . Это намного сложнее. Его нельзя просто отменить.
Вы обнаружите, что редко что-то кроме хэша пароля, и ничего не зашифровывается. Объем накладных расходов, которые вы имели бы при шифровании вашей базы данных, будет огромным.
Я полагаю, вы могли бы применить подобный шаблон соли / хэша к имени пользователя, но тогда у вас есть подводные камни. Что делать, если вы хотите использовать это имя пользователя в своем коде? Что делать, если вы хотите проверить, чтобы он был уникальным для таблицы?
2nd Edit: Что такое односторонний хеш? Я имею в виду, технически, могу ли я не перепроектировать мой исходный код? Возможно, это плохой вопрос, потому что я мало знаю об одностороннем хешировании.
См. Выше ( или нажмите здесь ). Односторонний хеш – это просто. Одностороннее отображение. A => B
и ничего больше. B !=> A
, и A
не может быть ничего, кроме B
Кто-то упомянул о выполнении операции XOR
. Хотя я чувствую, что производительность в значительной степени незначительна, я провел быстрый тест.
function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); }
Теперь запустите
$start_time = $this->microtime_float(); for($i = 0; $i < 100000; $i++) { $sha = sha1(sha1(microtime()) . sha1(microtime())); } $end_time = $this->microtime_float(); echo "1000 in " . ($end_time-$start_time) . " for CAT\n"; $start_time = $this->microtime_float(); for($i = 0; $i < 100000; $i++) { $sha = sha1(sha1(microtime()) ^ sha1(microtime())); } $end_time = $this->microtime_float(); echo "1000 in " . ($end_time-$start_time) . " for XOR\n";
Повторяйте столько, сколько хотите. Первоначальная запись использует журнал ошибок, и я получил следующие результаты:
1000 in 0.468002796173 XOR 1000 in 0.465842008591 XOR 1000 in 0.466115951538 XOR 1000 in 0.498080968857 CAT 1000 in 0.506876945496 CAT 1000 in 0.500174045563 CAT
Стандартная практика с паролями – не хранить исходный пароль в любом месте. Unix-пароли были зашифрованы «склепом», который использовал бы случайную соль. Сама соль хранилась в первых двух символах зашифрованного пароля. Когда пользователь вводит свой пароль, система будет использовать два символа зашифрованного пароля в качестве соли для шифрования введенного пароля, и если зашифрованный результат совпадает с сохраненным зашифрованным паролем, это было совпадение. Аналогичные вещи можно сделать с помощью паролей MD5.
Вот почему хорошие сайты никогда не будут отправлять вам ваш пароль, но вместо этого вы сбросите свой пароль на одноразовое значение – потому что они не знают ваш пароль.
Чтобы немного расширить это: MD5-хэш – это односторонняя функция – если у вас есть то же значение, вы получаете один и тот же хеш, но вы не можете взять хэш и каким-то образом превратить его в значение. Существует небольшая, но конечная вероятность того, что два значения будут выдавать один и тот же хеш (вероятность становится выше, чем больше исходных строк или чем меньше хэш), но они выбирают алгоритмы хеширования, чтобы сделать так, что две строки будут выбирать поскольку пароли имели бы хэш с тем же значением почти бесконечно малым. Вы можете думать о одностороннем хеше как о мясорубке – вы можете посмотреть мясо, которое выходит из вашей мясорубки, и посмотреть, есть ли это корова, ягненок или свинья, но вы не можете пройти через другой путь и верните корову.
Из-за этого никто не может восстановить ваш пароль, потому что он никогда не хранится нигде в своей системе, а только его хэш.
Этот вопрос может противоречить вышеизложенному, но должна ли моя соль когда-либо быть случайно генерируемой ценностью? Если да, то когда это может быть полезно?
Соли должны быть случайными. Их единственное использование – сделать атаки грубой силы на хеши намного дороже. Что-то называемое «радужным столом» (которое является причудливым именем для базы данных, где кто-то заранее проложил целую кучу возможных паролей и позволяет вам искать пароли, если вы знаете хэш) позволяет принимать несоленые хэши паролей и поворачивать их в пароли в доли секунды во многих случаях.
Соли умеренного размера могут увеличивать сложность предвыборной атаки грубой силы экспоненциально. Для каждого отдельного бита случайных данных в вашей соли вы удваиваете время, необходимое для предвыборной атаки грубой силы. Для каждого уникального значения соли в вашей базе данных злоумышленник должен начать работу, атакуя пароль, защищенный этой солью.
Если у вас было 1 кБ случайной соли для пароля каждого пользователя, предварительно вычисленные хэши выходили из окна. Вы не повлияли бы на количество времени, которое потребуется для принудительного использования пароля одного пользователя.
Один из способов сделать жизнь злоумышленника более сложной задачей – сделать процесс хэширования вычислительно интенсивным (например, 5000 раундов sha1 (соль + sha1 (соль + sha1 (соль + пароль))). Вы должны сделать это только для каждой попытки входа в систему. Атакующий должен сделать это для каждой комбинации соли + пароль, которую они хотят угадать. Вы должны решить, стоит ли это для ваших нужд. Ответ, вероятно, нет.
Изменить: кроме паролей, в пользовательской системе, что еще нужно зашифровать как хорошую практику? Записывают ли они имена пользователей или что-то еще?
Я параноик, но я бы сказал, что любая информация, которую вам владелец сайта не нужна, пока пользователь не вошел в систему, должен быть зашифрован производным от пароля пользователя. Таким образом, у злоумышленников нет доступа, потому что у вас нет доступа.
Например, для онлайн-системы обработки заказов вам может понадобиться почтовый адрес, его имя и последний заказ, не зашифрованный, но их история заказов и любимый цвет могут быть зашифрованы с помощью пароля учетной записи.
Обратите внимание: если вы это сделаете, и они потеряют свой пароль, также будет потеряна защищенная информация.
2nd Edit: Что такое односторонний хеш? Я имею в виду, технически, могу ли я не перепроектировать мой исходный код? Возможно, это плохой вопрос, потому что я мало знаю об одностороннем хешировании.
Хэш – это метод систематического извлечения информации. Скажите, что вы начинаете со строки и производят «srflcdos», выбрасывая всех, кроме каждого четвертого персонажа. Текст, который я «хэшировал», может быть: «копье, если рыба лежит спокойно, не сидите!», Или это может быть: «supercalifragilisticexpialidotious». Нет никакого способа доказать ни один из способов.
Криптографические хеши делают намного больше смешивания и других преобразований вместе с выбросом, чтобы сделать их более безопасными для небольших объемов входных данных и во избежание утечки каких-либо фактов вообще о входных данных. В качестве примера небезопасного хэша, если вы знаете, что всякий раз, когда вход содержит букву A, 12 бит хэша равно 1, тогда вы публикуете информацию об исходном тексте, а результат не является криптографически защищенным хэшем.
Принцип заключается в том, что вы не можете перепроектировать процесс, если между каждым преобразованием вы выбрасываете информацию, жизненно важную для изменения предыдущей трансформации. MD5sum производит 128 бит вывода, независимо от того, помещаете ли вы 1 бит или 12 петабайт информации. Вы, очевидно, не можете сжать 12 петабайт в 128 бит, так что информация явно выбрасывается в процессе вычисления хэша.
Никогда не храните пароль обратимым образом, всегда используйте односторонние хэш. Проверка выполняется путем хеширования введенного пароля и проверки двух хэшей друг против друга.
Вы должны сохранить хэш своего пароля вместо фактической читаемой строки, а также рассмотреть возможность использования «Соления» для дополнительной безопасности
На эту тему много вариантов.
Для получения хорошей информации, пожалуйста, прочтите следующее: http://en.wikipedia.org/wiki/Digest_access_authentication .
Затем прочтите следующее: http://tools.ietf.org/html/rfc2617
Обычно: вы храните только дайджест. Никогда не вводите пароль.
Следуя RFC2617, вы должны сохранить дайджест имени пользователя, области и пароля.
Клиент («агент») принимает имя пользователя, пароль, область и т. Д. И создает дайджест, который он отправляет на ваш сервер.
Ваш сервер, основанный на имени пользователя, просматривает его версию дайджеста.
Если их дайджест == дайджест, сохраненный на сервере, вы соглашаетесь с паролем (и всем остальным).
Если их дайджест! = Дайджест, сохраненный на сервере, вы не согласны с паролем (или чем-то еще). Это означает, что они не получили права на королевство или имя пользователя, или они не получили право на право, или что-то еще пошло не так. Им нельзя доверять.
Полный RFC2617 включает в себя другие данные, чтобы вычислить дайджест других материалов и дайджест пароля, чтобы быть абсолютно уверенным, что клиент выполняет ответ.
Я настоятельно рекомендую использовать MD5. Для получения дополнительной информации ознакомьтесь с разделом [MD5] в Википедии . Вместо этого я рекомендую использовать алгоритм хэширования SHA-1.
Избегайте использования хэшей MD5, если это возможно, так как это довольно сложно.
Альтернативами являются SHA1 или даже лучше SHA256 или SHA512.
2nd Edit: Что такое односторонний хеш? Я имею в виду, технически, могу ли я не перепроектировать мой исходный код? Возможно, это плохой вопрос, потому что я мало знаю об одностороннем хешировании.
«Один способ» в криптографии означает «трудно инвертировать». Проще говоря, это означает, что если я дам вам sha1(password)
, вы не сможете найти password
в любое разумное время.
Это называется вычислительно односторонним . Многие люди путают это для другого определения одностороннего (из математики), что означает «не один к одному» , что здесь не применяется.
Причина, по которой вы храните хешированный пароль, состоит в том, что если кому-то удается получить данные в вашей пользовательской таблице, они все равно не могут войти в систему. Односторонний хэш не может быть расшифрован (даже тот, кто зашифрован это!), поэтому очень сложно использовать хешированный пароль для чего угодно.
Поскольку вы не можете расшифровать пароль в базе данных, вам нужно взять пароль, который был введен, и повторить тот же процесс для хеширования, а затем сравнить хешированные значения, чтобы найти совпадение. Из-за этого ваша соль не может быть абсолютно случайной, так как вы получите разные результаты.
Кроме того, вы не хотите, чтобы пароль был передан в незашифрованном виде, поэтому страницы входа в систему обычно являются HTTPS-страницами.
"Верный?"
Если вам нужен двоичный ответ:
1