Есть ли преимущество у этого хэша для безопасности?

Есть ли преимущество в

sha1(sha1(sha1($password. $salt)));

В основном, имея несколько стихов sha1 только один sha1

sha1($password. $salt);

person Jason    schedule 20.01.2011    source источник
comment
если ваш $salt сильный, длинный и представляет собой случайное сочетание символов, последнего должно быть достаточно. в основном, последнее уязвимо только в том случае, если кто-то скомпилировал радужные таблицы с вашей солью, чего почти нет, если ваш $salt достаточно силен, например. 12@!(*E&HD*&@#HE!_)UDJNuyhdsbq897cuddaadn*&BD#NXUHSD8uyahs... использование нескольких sha1, на мой взгляд, немного более безопасно.   -  person Stoic    schedule 20.01.2011
comment
Спасибо. Я использую сильную соль.   -  person Jason    schedule 20.01.2011
comment
Связанный вопрос с некоторой полезной информацией и обсуждением: Много итераций хэша, каждый раз добавлять соль?   -  person ircmaxell    schedule 20.01.2011


Ответы (4)


Повторяю, не пытайтесь НЕ сделать свой хэш пароля более безопасным, выполняя «особые» действия с вашим хэшем.

Во-первых, побочным эффектом sha1(sha1(sha1($input))) является только увеличение вероятности столкновения* на каждой итерации. Повышение вероятности столкновений — очень плохая вещь.

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

PHPass на самом деле использует bcrypt, который представляет собой алгоритм, разработанный для предотвращения радужных таблиц, словарей и атак грубой силы. Вы можете инициализировать его несколькими раундами: чем больше раундов, тем больше времени требуется для вычисления хэша. Таким образом, вы можете создавать более надежные хэши, если вычислительная мощность увеличивается.


* Первый вызов sha1() принимает бесконечные входные данные и создает один из 2160 выходных данных. Вторая итерация принимает 2160 входных данных и создает один из x выходных данных, где x <= 2160. Третья итерация принимает x входных данных и создает один из y выходных данных, где y <= x <= 2160.

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

person Andrew Moore    schedule 20.01.2011
comment
Сам phpAss хеширует, используя несколько итераций (просто взгляните на самый первый метод), это хорошая практика безопасности. - person Alix Axel; 20.01.2011
comment
@Alex Axel: В портативном режиме да. НО, он всегда повторно хеширует предыдущий хеш, объединенный с паролем ( sha1($hash . $password) ), сохраняя возможные входы бесконечными, поэтому не увеличивая вероятность столкновения... Обычно $password является единственным источником бесконечного ввода, если вы не используете $salt для каждого хэша. . - person Andrew Moore; 20.01.2011
comment
@Эндрю Мур: В вашем аргументе есть ошибка, bcrypt имеет подобные шансы на коллизии, как и sha1 - оба перефразируются несколько раз. - person Alix Axel; 20.01.2011
comment
@ Аликс: нет. вызов sha1(...sha1($f00)) будет иметь вырождающееся количество коллизий. Чтобы понять почему, давайте назовем его A(B(C($foo))). Теперь мы знаем, что C будут иметь коллизии с бесконечности › 2^256. Таким образом, все коллизии для C автоматически становятся коллизиями как для A, так и для B, поскольку ввод не изменяется. То же самое касается только B and A. So the total collisions are much more than for C`. Но если бы вы сделали A(B(C($foo) . $foo) . $foo), у него было бы точно такое же количество столкновений, что и C... - person ircmaxell; 20.01.2011
comment
@Alix Axel: bcrypt на самом деле не повторяет никаких преобразований пароля. bcrypt выполняет итерацию по вектору инициализации, преобразовывая его несколько раз, чтобы создать хеш, используя результирующий вектор. Проще говоря, он несколько раз преобразует соль (IV), пока она не станет достаточно криптографически безопасной для создания хэша с ее использованием. Чтобы сравнить ввод с хэшем bcrypt, вам нужен сохраненный хеш, чтобы извлечь исходный IV (хранящийся в хэше, уникальный для каждого), позволить bcrypt снова преобразовать вектор, хэшировать необработанный ввод и сравнить два полученных хэша. . - person Andrew Moore; 20.01.2011
comment
КОММЕНТАРИЙ: На самом деле, после пересмотра спецификации bcrypt, она использует как IV, так и входные данные для создания подразделов... Не то чтобы это в любом случае влияет на вероятность коллизий. - person Andrew Moore; 20.01.2011

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

$hash = sha1($password . $salt);

for ($i = 1; $i <= 65000; ++$i)
{
    $hash = sha1($hash . $salt);
}

Кроме того, прочитайте этот замечательный пост в блоге или хотя бы эту короткую цитату:

Чем лучше вы сможете оптимизировать хеш-функцию пароля, тем быстрее будет работать хэш-функция пароля, тем слабее будет ваша схема. MD5 и SHA1, даже обычные блочные шифры, такие как DES, рассчитаны на высокую скорость. MD5, SHA1 и DES — слабые хэши паролей. На современных процессорах необработанные строительные блоки криптографии, такие как DES и MD5, могут быть разделены на биты, векторизованы и распараллелены, чтобы сделать поиск паролей молниеносным. Реализации Game-over FPGA стоят всего сотни долларов.

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

Каково здесь современное состояние?

Во-первых, то, что уже дает вам ваша операционная система: схема паролей, «оптимизированная» для больших вычислительных затрат. Самая известная из них — схема PHK FreeBSD MD5.

Разница между схемой PHK и той, которую вы собирались использовать для своего приложения социальной корзины покупок 2.0, проста. Вы просто собирались запустить MD5 с солью и паролем и сохранить хэш. PHK выполняет тысячи итераций MD5. Это называется «растяжка».

person Alix Axel    schedule 20.01.2011
comment
Всегда повторно вводите как можно больше информации в каждый цикл хеширования. Я бы предложил также добавить пароль к внутреннему вызову sha1. См. этот ответ для получения дополнительной информации. Также см. Стандарт PBKDF2 для расширения ключей - person ircmaxell; 20.01.2011
comment
Не используйте sha1($hash . $salt), если только $salt не меняется при каждом создании хэша. Если это не так, вы увеличиваете свои шансы на коллизии по той же причине, что и в мой ответ. - person Andrew Moore; 20.01.2011

Краткий ответ: нет. Когда вы связываете два хэш-алгоритма, все, что вы делаете, — это создаете еще один хэш-алгоритм с неизвестными свойствами (с точки зрения безопасности). Используйте соль (а еще лучше HMAC).

person Jeff Hubbard    schedule 20.01.2011

Чем больше раз он должен пройти процесс хэширования, тем больше времени потребуется для хеширования и тем меньше попыток злоумышленник получит в день. Если однократное хеширование занимает 10 мс, а десятикратное хеширование — 100 мс, то злоумышленник может попытаться ввести 6000 паролей в минуту при однократном хешировании и 600 паролей в минуту при десятикратном хешировании. Конечно, с веб-приложением попытка перебора со скоростью 6000 или 600 в минуту по существу является DOS-атакой. Криптографические хэши, как правило, занимают некоторое время для этой цели, и также обычно хэшируется несколько раз.

Вероятно, вам следует использовать sha512 вместо sha1, что вы можете сделать с hash() как hash('sha512',$stringtobehashed);, sha512 также занимает примерно в 5 раз больше времени, чем sha1 для хеширования.

person Phoenix    schedule 20.01.2011
comment
Это при условии, что он работает на одном ядре без параллелизма. Теоретически он может работать на многих ядрах (обычны 12-ядерные системы, а у графических процессоров гораздо больше). Не говоря уже о том, что с помощью конвейерной обработки одновременно можно запускать более одного хэша, поэтому реальное число, вероятно, намного превышает 6 тыс. паролей в минуту (я был бы удивлен, если бы приличное оборудование не могло достичь 100 тыс. в минуту или более)... - person ircmaxell; 20.01.2011