Intereting Posts
PHP Stomp: чтение всех сообщений в очереди Могу ли я получить поддержку интеграции Sagepay Server inFrame Как избежать инъекций mysql с использованием PDO Как сохранить и получить содержимое изображения из базы данных с помощью Laravel WooCommerce – добавление категории товаров в таблицу заказов Как остановить mod_rewrite от добавления ссылок на url? Как сопоставить только последние обновленные записи в Doctrine? Как искать URL-адреса, которые не находятся ни в одном теге html, а затем превращать их в гиперссылки? ajax: responsetext возвращает весь мой PHP-код локально php – simpleXML Как получить доступ к определенному элементу с тем же именем, что и другие? синтаксическая ошибка, неожиданный «if» (T_IF) Symfony3 как хранить роли пользователя в базе данных Как вы выполняете preg_match, где шаблон является массивом, в php? Связанные с Magento образцы цвета продукта Выбор динамического значения по умолчанию в <SELECT>

openssl_digest vs hash vs hash_hmac? Разница между SALT & HMAC?

Я хочу использовать SHA512 для хранения паролей. Для этого, какой из openssl_digest , hash и hash_hmac следует использовать и почему?


В чем разница между SALT & HMAC ?


Я просто прочитал, что HMAC построен поверх хэш-функции.

Итак, SHA512+SALT+HMAC действительно необходим или SHA512+SALT или SHA512+HMAC ?

    Итак, во-первых, давайте разберемся. openssl_digest() === hash() . Это просто другая функция с другим именем, которое делает то же самое. Он вычисляет криптографический хеш ввода.

    Итак, теперь у нас возникает вопрос: при хранении паролей, что лучше: hash или hash_hmac ?

    Короткий ответ:

    ни

    Длительный ответ:

    Как оказалось, The Rainbow Table Is Dead . Просто использование hash($password . $salt) hash_hmac($password, $salt) hash($password . $salt) или даже hash_hmac($password, $salt) недостаточно для хранения паролей. Период. Если вы это сделаете, остановитесь прямо сейчас.

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

    Но, как выясняется, есть способ сделать эти быстрые функции хеширования более дорогими. На самом деле это довольно просто: итерация.

    Теперь я знаю, о чем вы думаете. Вы просто перейдете через хэш:

     function hash_password($password, $salt) { $hash = hash("sha512", $password . $salt); for ($i = 0; $i < 1000; $i++) { $hash = hash("sha512", $hash); } } 

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

     function hash_password($password, $salt) { $hash = hash("md5", $salt . $password); for ($i = 0; $i < 1000; $i++) { $hash = hash("md5", $hash . $password); } } 

    Фактически, это именно то, что использует PHPASS (слегка измененный, но это базовый алгоритм) …

    Итак, теперь 1 вызов hash_password выполняет 1000 хэш-циклов.

    Но можем ли мы улучшить это?

    Ну, как оказалось, мы можем. Следующей логической задачей было бы увидеть, можем ли мы получить больше циклов хеширования за такое же количество времени. И здесь приходит hash_hmac() . Как оказалось, HMAC использует два хэш-цикла каждый раз, когда он hash_hmac() . И поскольку это все C, это занимает примерно в 1,5 раза больше времени, которое делает hash() чтобы сделать один раунд.

    Таким образом, это означает, что если мы заменим hash hash_hmac , мы сможем мгновенно увидеть увеличение на 33% объема работы, выполняемой в указанное время. Итак, теперь мы здесь:

     function hash_password($password, $salt) { $hash = hash_hmac("md5", $salt, $password); for ($i = 0; $i < 1000; $i++) { $hash = hash_hmac("md5", $hash, $password); } } 

    И это фактически базовый внутренний цикл PBKDF2 .

    Но можем ли мы поправляться?

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

    Ну, как оказалось, мы можем просто использовать bcrypt , который является адаптивным алгоритмом хэширования. Он имеет преимущество в том, что он использует больше памяти, чем вышеупомянутые алгоритмы (порядка от 4 до 5kb). Таким образом, он более устойчив к распараллеливанию. И он сопротивляется жестокому форсированию, поскольку он является дорогостоящим.

    К счастью, он доступен для PHP:

     crypt($password, '$2y$07$usesomesillystringforsalt$') 

    Обратите внимание, что crypt() использует множество алгоритмов, но алгоритмы $2y$ и $2a$ – это bcrypt .

    Но можем ли мы улучшить это?

    Вид. Существует относительно новый алгоритм, называемый scrypt . Это лучше, чем bcrypt, потому что это так же дорого вычислительно, но использует LOT больше памяти (от порядка 20 мб до 40 мб для хеширования одного пароля). Поэтому он еще более устойчив к распараллеливанию …

    К сожалению, scrypt еще не доступен на PHP (я работаю над этим). До тех пор, используйте bcrypt

    Примечание

    После недавних уроков LinkedIn , LastFM , Hotmail , Gawker и т. Д. Доказательство очевидно, что многие люди делают это неправильно. Не делайте это неправильно, используйте библиотеку с проверенным алгоритмом. Используйте CRYPT_BLOWFISH (bcrypt), используйте PHPASS, используйте PasswordLib . Но не придумывайте свои собственные, потому что вы не хотите тянуть зависимость … Это просто халатность.

    Больше информации:

    • Правильно солить пароли – дело против перца
    • GPU Accelerated PBKDF2
    • Многие хеш-итерации, каждый раз приносят соль?
    • MD5 декодирование, как они это делают

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

    Соль используется, чтобы добавить немного «случайности» в текст, который должен быть зашифрован или хэширован. Дело в том, что даже если вы зашифруете один и тот же текст несколько раз, вы получите разные результаты. Это затрудняет некоторые атаки. Это то, что вы хотите: SHA512(salt+password) .

    Для хранения паролей самым безопасным способом я мог бы представить:

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

    • Клиент (код JavaScript?) Будет генерировать значение соли.
    • Затем клиент объединяет соль и пароль и запускает результат через ваш алгоритм хэширования.
    • Затем клиент передает значение соли и хеша на сервер, который хранит его (предпочтительно в разных местах).

    Чтобы проверить пароль, выполните следующие действия:

    • Передайте соль клиенту.
    • Клиент объединяет соль и вводит пароль, запускает его через ваш алгоритм хэширования.
    • Клиент отправляет хеш-значение серверу.
    • Сервер сравнивает хэш-значение с сохраненным значением хэш-функции. Если они совпадают, это был тот же пароль.

    Конечно, вы можете передавать пароль в виде открытого текста и делать все соление и хеширование на сервере, но это значительно ослабит ваше решение. Вы никогда не должны передавать пароль в текстовом виде.

    Но проблема «передать соль клиенту» может быть проблемой. Один из способов, который я мог бы себе представить, – это как-то вывести соль из имени пользователя (проще всего: просто ввести lowercase(username) + password ), но проблема в том, что соль будет предсказуемой и, таким образом, решение немного. Тем не менее, это все еще лучше, чем передача «сырого» хеша, и вам даже не нужно было бы хранить соль, поскольку вы могли бы извлекать ее из имени пользователя каждый раз. Если ваш пароль DB будет украден, он все равно будет противостоять атаке радужного стола с помощью этого подхода «солить с именем пользователя».

    Проблема в том, что атака «человек в середине» по-прежнему возможна. Если злоумышленник перехватывает имя пользователя и хеш, он имеет всю соответствующую информацию, и он не будет отличаться от передачи пароля открытого текста. Таким образом, вы можете защитить соединение с SSL (HTTPS).

    По мнению экспертов ИТ-безопасности:

    Использовать Bcrypt Источник: https://security.stackexchange.com/a/10905/7599 .

    Я бы дал ответ в соответствии с точкой зрения SO.

     openssl_digest vs hash vs hash_hmac 
    1. openssl_digest – вычисляет дайджест.
    2. хэш Создание хэш-значения (дайджест сообщения)
    3. hash_hmac – Генерировать значение хеш-ключа с использованием метода HMAC

    В криптографии хэш-код аутентификации сообщения (HMAC) представляет собой конкретную конструкцию для вычисления кода аутентификации сообщения (MAC), включающего криптографическую хеш-функцию в сочетании с секретным ключом.

    Как сказал ircmaxell, hash или hash_hmac не лучше для хранения паролей с SHA-512. Я бы сказал, вы можете использовать openssl_digest для хранения паролей.

    См. Библиотеку SHA-512 для PHP

     SALT vs HMAC 
    1. Хэш в этом контексте является односторонней функцией, то есть функцией, которая позволяет легко найти результат из аргумента (пароля), но трудно (или невозможно) найти любой аргумент, который генерирует данный результат.
    2. Соль – это некоторые вспомогательные данные, которые дополняют аргумент хэш-функции. Это полезно, поскольку это предотвращает случайное обнаружение паролей через наблюдение, что два хэшированных пароля имеют одинаковые значения. С солью сохраненное / переданное значение будет только идентичным, если совпадают соль и пароль.
    3. HMAC ссылается на применение хэша (и дополнительной соли) на «код аутентификации сообщения», который, в зависимости от контекста, может быть паролем … или, по крайней мере, нет ничего, что могло бы остановить передачу пароля в HMAC как если это был код аутентификации сообщения.

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

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

    Сравнение HMAC и Salt не является логичным. Лично я использовал соль и функцию хеша … и я не был бы параноик о силе хеш-функции, так как вряд ли она будет слабым звеном в любой практической системе ….

    См. http://www.derkeiler.com/Newsgroups/sci.crypt/2006-01/msg00321.html.