хранилище паролей в mysql для веб-сайта пользовательского контента

Для хранения паролей пользователей я использую SHA 256 + соление. Просто хотел подтвердить, верны ли они. Бизнес-требование: пароль должен состоять минимум из 8 и максимум из 32 входов. (допустим любой ввод, кроме пробела)

Таким образом, чтобы выполнить эти требования, план таков:
Передняя часть — проверить максимальное количество входных данных, равное 32, и минимальное значение, равное 8.

Базовая схема базы данных (MySQL) будет следующей:
pass_hash(64) CHAR — хранить хэш пароля
pass_slt(32) VARCHAR — хранить уникальную соль для каждого пользователя

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

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


person Ian    schedule 03.11.2010    source источник


Ответы (2)


О солях:

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

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

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

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

Дополнительный уровень безопасности, помимо соления, заключается в том, чтобы сделать хеширование паролей «дорогим». Например, когда вы хешируете (соленый) пароль, вы фактически хэшируете конкатенацию в 10000 раз больше последовательности соль+пароль. Это делает проверку пароля в 10000 раз дороже, как для вас, так и для злоумышленника. Часто бывает так, что проверку законных паролей можно сделать вычислительно более сложной без заметного эффекта (даже если вы проверяете 100 пользовательских паролей в секунду, вы все равно можете выделить на это 100 мкс, и это займет только 1% вашего времени обработки), но усложнить задачу злоумышленнику в 10000 раз — хорошая идея.

О языках:

Основная проблема с паролями, отличными от ASCII, заключается в том, что некоторые глифы могут использовать несколько кодировок. Например, буква «é» может быть закодирована с помощью Unicode как одна кодовая точка (U+00E9 СТРОЧНАЯ ЛАТИНСКАЯ БУКВА E С ОСТРОЙ) или как две кодовые точки (U+0065 СТРОЧНАЯ ЛАТИНСКАЯ БУКВА E, за которой следует U+0301 КОМБИНИРОВАНИЕ). ОСТРЫЙ АКЦЕНТ). Обратите внимание, что в этом примере речь идет о довольно распространенном французском письме, не столь причудливом (с точки зрения компьютера), как китайское или корейское. Проблемы с кодировкой можно решить с помощью Форм нормализации Unicode, но это непростая задача программирования. Могут помочь некоторые среды программирования (например, в Java используйте java.text.Normalizer, который реализует UNF).

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

Я бы порекомендовал попытаться принудительно использовать пароли только для ASCII, если это возможно, или в противном случае укусить пулю: выполнить UNF (с формой NFD), затем кодировку UTF-8. Полученная последовательность байтов — это то, что отправляется на этап хэширования.

person Thomas Pornin    schedule 03.11.2010

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

Что касается многоязычности, вы должны быть последовательны в отношении того, какую кодировку символов вы используете в своем приложении и для чего точно вы вызываете SHA-256.

person Matthew Flaschen    schedule 03.11.2010
comment
Под кодировкой вы подразумеваете использование UTF-8 для всех данных таблицы, верно? Итак, если пользователь вводит китайские иероглифы, я использую SHA 256 для этих китайских иероглифов + применяю английскую соль, или мне нужна китайская соль? - person Ian; 03.11.2010
comment
Да, UTF-8 должно быть в порядке. Обратите внимание, что соль добавляется перед перемешиванием. Это должна быть просто случайная строка, не предвзятая к какой-либо письменности (английской, китайской и т. д.); это также может быть случайный массив байтов, и в этом случае вы должны использовать, например. ДВОИЧНЫЙ (32). - person Matthew Flaschen; 03.11.2010
comment
Это действительно не имеет значения. Пока соль случайна с любым из символов в диапазоне Unicode. - person Zabba; 03.11.2010