Где вы храните нитки соли?

Я всегда использовал правильную строку соли для каждой записи при хешировании паролей для хранения базы данных. Для моих нужд хранение соли в БД рядом с хешированным паролем всегда работало нормально.

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

С точки зрения безопасности, стоит ли хранить соли в другом месте? Рассмотрим веб-приложение с серверным кодом и БД на одном компьютере. Если соли хранятся в плоском файле на этой машине, есть вероятность, что если база данных будет скомпрометирована, файл солей тоже будет.

Есть ли какие-либо рекомендуемые решения для этого?


person friedo    schedule 02.08.2009    source источник
comment
Если есть место, где вы можете хранить соль, до которой не может добраться злоумышленник, вам также следует просто сохранить там пароли. Но почему бы не использовать разные соли для каждого пароля?   -  person jrockway    schedule 03.08.2009
comment
Он использует различную соль для каждого пароля, jrockway.   -  person Amber    schedule 03.08.2009
comment
Насколько велики ваши соли? Ваши соли должны быть достаточно большими (32 бита?), Чтобы практически не было шансов, что для них была предварительно вычислена радужная таблица.   -  person M. Dudley    schedule 03.08.2009
comment
@emddudley в последнее время я имел обыкновение использовать 64-битное целое число в качестве соли, но нет причин, по которым я не могу сделать их больше.   -  person friedo    schedule 03.08.2009
comment
Я также хотел бы добавить этот вопрос администраторов баз данных в смесь dba.stackexchange.com/questions/7492 /   -  person jcolebrand    schedule 02.11.2011
comment
Автор PWDTK здесь sourceforge.net/projects/pwdtknet, честно говоря, я бы не стал беспокоиться и я бы просто сохраните соль в той же БД, что и пароль. В любом случае вы всегда должны предполагать, что соль известна злоумышленнику, поэтому ваше внимание должно быть сосредоточено на использовании БОЛЬШОЙ КРИПТО-СЛУЧАЙНОЙ соли и выполнении достаточного растягивания клавиш (итераций в PBKDF2), так что создание даже одной радужной таблицы для одной известной соли невозможно. Честно говоря, то, что вы пытаетесь достичь, помещая соль в другое место, - это Security by Obscurity и обычно не приносит пользы, когда вы смотрите на такие вещи, как другой сервер, который потенциально может выйти из строя.   -  person thashiznets    schedule 10.05.2013
comment
@friedo, одной соли мало. Используйте перец.   -  person Pacerier    schedule 16.02.2015
comment
@thashiznets, это не безопасность посредством неизвестности, если мы говорим о перце. Безопасность по паролю.   -  person Pacerier    schedule 16.02.2015
comment
@Pacerier pepper - это, по сути, глобальная соль, вопрос говорит о том, чтобы скрыть соль, которая на самом деле ваша схема пароля должна быть достаточно хорошей, чтобы даже если у них есть соль, им потребуется слишком много времени, чтобы создать радужную таблицу. Тем не менее, это может иметь небольшую ценность для защиты от пользователей-идиотов, использующих пароль в качестве пароля или что-то в этом роде.   -  person thashiznets    schedule 20.02.2015


Ответы (7)


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

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

person Amber    schedule 02.08.2009
comment
Согласовано. Модель угрозы, от которой вы защищаете, отдельно сохраняя соль, - это пользователь, который может каким-то образом получить доступ к соли в БД с помощью гнусных средств, но не хеш-код (в БД). И что этот человек заранее начнет вычислять радужную таблицу, предполагая, что он сможет найти хэш позже. Это не невозможно, но и не стоит инженерных усилий для защиты от этой единственной атаки. - person Tom Ritter; 03.08.2009
comment
Хороший пост, мне было интересно то же самое. Я никогда не думал о соли для каждого пользователя. Я думал, что одна соль будет работать для всех пользователей. Как насчет соли, которая хранится в виде XML-файла, загружаемого сервером приложений? или, может быть, каким-то образом жестко запрограммирован в сервлет? - person jigzat; 25.07.2012
comment
@Jigzat - Солить бессмысленно, если у вас нет отдельной соли для каждого пользователя. Смысл солей состоит в том, чтобы сделать взлом хэшей отдельной задачей для каждого пароля пользователя; если соль для всех одинакова, то это не так. - person Amber; 29.07.2012
comment
@TomRitter - это не единственный случай. вы предполагаете, что все пароли сложные. некоторые злоумышленники могут взять соль и хэш и проверить только 10 000 наиболее распространенных паролей. так они получат приличное количество людей. если, однако, у них нет доступа к соли, это похоже на то, что у пользователя есть более длинный и более безопасный пароль. Теперь вопрос о том, насколько вероятно, что база данных соли останется в безопасности, пока база данных паролей будет украдена, является предметом обсуждения, но это отдельный вопрос. - person chacham15; 27.04.2013
comment
@ Эмбер, я считаю, что ТомРиттер прав. Хранение соли отдельно означает разницу между принуждением злоумышленника использовать атаку грубой силы и более простой атакой по словарю. Если вы знаете соль, вы можете просто добавить ее во время атаки по словарю. Если вы можете на 100% защитить свою соль, вы можете просто использовать ту же соль и заставить злоумышленников перебрать все (даже для пользователей, которые используют пароль в качестве пароля). Но можете ли вы защитить свою соль .... вероятно, нет. Таким образом, можно уменьшить количество точек отказа, сохранив его рядом с хешем и обеспечив соблюдение более строгих правил паролей. - person Ultratrunks; 12.11.2013
comment
Посол @Jigzat не является бессмысленным, если у вас нет отдельной соли для каждого пользователя, если только у вашей соли уже нет широко распространенной радужной таблицы, и все уже знают, какую из них попробовать. Более вероятно, что если они получат вашу соль, им придется регенерировать другую таблицу только для ваших вещей. Это все равно их замедлит. Конечно, все равно не лучше иметь разные для каждого. - person Aaron R.; 16.05.2014
comment
Восстановление отдельной таблицы - то же самое, что и перебор одного пароля. Смысл солей не в том, чтобы предотвратить перебор отдельных паролей, поэтому на самом деле нет особого способа получить эффективную выгоду от наличия общей соли. Вы могли бы просто не использовать соли и просто хэшировать свои пароли немного иначе, чем все остальные, если бы вы собирались это сделать. (Но не используйте отдельные соли, потому что это действительно безопасный способ.) - person Amber; 16.05.2014
comment
@ Эмбер, я думаю, тебе здесь что-то не хватает. Когда вы знаете соль, количество паролей, которые вам нужно перебрать, существенно уменьшается, не так ли? Потому что вы уже знаете большую часть пароля (при условии, что соль длиннее, чем пароль пользователя), и поэтому размер радужной таблицы значительно меньше. Если соль скрыта размером с грубую силу, это кажется мне невозможным, потому что вам придется создать радужную таблицу, содержащую хэши всех возможных солей, предполагая, что вы не можете получить скрытую соль. - person doliver; 27.01.2015
comment
Я добавлю, что более разумной стратегией определенно было бы использование более сильной функции хеширования, а не использование скрытой соли для защиты от атак грубой силы, поэтому результат будет таким же. - person doliver; 27.01.2015
comment
Курс веб-разработки по udacity, проведенный соучредителем Reddit, также затрагивает это, и это был первый раз, когда я узнал об этом, и я понял это прямо тогда. - person Muhammad Umer; 16.02.2015
comment
@doliver, поскольку оба метода вряд ли будут успешными в разумные сроки, я считаю, что это чисто академический аргумент, и на практике нет никакой реальной пользы от сокрытия соли. - person Nick Coad; 30.10.2015

Я поделюсь с вами несколько иначе.

Я всегда храню соль, смешанную с хешем паролей с солью.

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

Мое обоснование такого подхода:

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

Если хэш соленого пароля хранится как есть, то может быть проведена атака грубой силой, чтобы получить пароль, который после соления и хеширования дает те же данные, что и хеш соленого пароля.

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

Вывод к этому ..

1) Никогда не храните данные, которые использует ваше приложение аутентификации, в точном виде.

2) По возможности держите логику аутентификации в секрете для дополнительной безопасности.

Сделайте еще один шаг…

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

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

Например, вы генерируете случайную соль размером 512 байт. Вы добавляете соль к своему паролю и получаете хэш SHA-512 вашего соленого пароля. Вы также генерируете случайное целое число 200. Затем вы сохраняете первые 200 байтов соли, за которыми следует хеш соленого пароля, а затем остаток соли.

При аутентификации ввода пароля пользователя ваше приложение передаст строку и предположит, что первый 1 байт данных - это первый 1 байт соли, за которым следует соленый хеш. Этот проход не удастся. Приложение будет продолжать, используя первые 2 байта данных в качестве первых 2 байтов соли, и повторять до тех пор, пока не будет обнаружен положительный результат после использования первых 200 байтов в качестве первых 200 байтов соли. Если пароль неправильный, приложение будет продолжать пробовать все перестановки, пока ни одна не будет найдена.

Плюсы этого подхода:

Повышенная безопасность - даже если ваша логика аутентификации известна, точная логика неизвестна во время компиляции. Практически невозможно провести атаку полным перебором, даже зная точную логику. Увеличенная длина соли еще больше повысит безопасность.

Минусы этого подхода:

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

Аутентификация неверных паролей потребует наибольших затрат на процессор. Это может быть контрпродуктивным для законных запросов, но повышает безопасность от злоумышленников.

Этот подход может быть реализован различными способами, и его можно сделать еще более безопасным, используя соли переменной ширины и / или хеши паролей с солью.

person Ibraheem    schedule 12.05.2013
comment
С вашим подходом вы просто добавляете секрет в свой процесс хеширования (алгоритм, который применяет соль). Этот секрет вы можете добавить намного проще, добавив перец к соли, я попытался указать на это в моем руководство. Современные хеш-функции, такие как BCrypt, будут применять соль самостоятельно, используя исходную соль на каждой итерации, так что вы все равно не сможете это контролировать. - person martinstoeckli; 13.05.2013
comment
@martinstoeckli Хотя вы правы в том, что BCrypt применяет соль самостоятельно, хранение этой соли + хеша зависит от вас как разработчика. Итак, вы можете легко добавить перец к хешу соли + и сохранить его в базе данных. Затем при последующем извлечении вы считываете значение из базы данных, удаляете значение перца и передаете оставшееся значение в BCrypt. - person PeterToTheThird; 29.05.2013
comment
@PeterToTheThird - это сведет на нет преимущество перца. Перец добавляет секрет на стороне сервера и работает только до тех пор, пока остается секретом (в отличие от соли). Типичная атака - это SQL-инъекция, когда кто-то получает доступ к базе данных, но не к коду, перец, хранящийся в базе данных, будет бесполезен. Большинство реализаций BCrypt автоматически добавляют соль к результирующему хэш-значению, поэтому это значение уже содержит соль, коэффициент стоимости, алгоритм и хеш. Эта строка может храниться в одном поле длиной 60 символов. - person martinstoeckli; 30.05.2013
comment
Чтобы добавить, при использовании функции усиления ключа, такой как BCrypt, у вас нет контроля над использованием соли. Однако, если вы хотите использовать перец, вы просто добавляете перец к соли и используете его в качестве соли с перцем вместо соли, вводимой в функцию хеширования. Таким образом, перец представляет собой подходящий фрагмент данных, который не хранится в базе данных, но встроен в код аутентификации или хранится в другом безопасном месте. Я подошел к проблеме с общей точки зрения, используя SHA-512 в качестве примера функции, но BCrypt и т. Д. Также можно использовать аналогичным образом. - person Ibraheem; 30.05.2013
comment
@Ibraheem - На самом деле перец нужно сочетать с паролем, а не с солью. В противном случае функции, которые возвращают соль в результирующем хэш-значении, возвращали бы объединенную соль-перец. Вы, наверное, задумывались о функциях, в которых соль нужно хранить отдельно. - person martinstoeckli; 31.05.2013
comment
@martinstoeckli - да, фактическая реализация зависит от того, какую хеш-функцию вы используете. Очевидно, вам необходимо принять во внимание параметры и выходные данные хэш-функции при реализации вашей логики аутентификации. В конечном итоге перец - это просто еще одна переменная, введенная в вашу хеш-функцию, которая не хранится в том же месте, что и соль и хеш. - person Ibraheem; 31.05.2013
comment
Это никоим образом не увеличивает безопасность. Если я могу загрузить вашу базу данных, я могу загрузить / реконструировать код вашего приложения. Безопасность через безвестность? Не совсем. - person Cypher; 14.06.2013
comment
@Cypher, хотя это технически возможно, извлечь эту информацию из базы данных, если бы у вас были доступные данные, было бы практически невозможно, и в этом весь смысл этого подхода - снизить практичность атаки. - person Ibraheem; 23.06.2013
comment
Я не согласен, поэтому и голосую против. Это никоим образом не увеличивает безопасность. - person Cypher; 24.06.2013

Часто они добавляются к хешу и хранятся в том же поле.

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

Если бы у вас было более безопасное место для хранения, имело бы смысл просто хранить там хэши.

person nobody    schedule 02.08.2009
comment
Но что произойдет, если все хешированные пароли будут утечкой, включая их соответствующую соль? Разве это не так небезопасно? - person mghaoui; 02.08.2012
comment
@mghaoui Но тогда, если вы хотите узнать пароль, вам все равно придется построить радужную таблицу для каждой соли, если только некоторые из солей не совпадают. - person Franklin; 06.11.2012

На основе книги Уильяма Пенберти «Разработка веб-приложений ASP.NET MVC 4»:

  1. Чтобы получить доступ к солям, хранящимся в отдельной базе данных, хакеры должны взломать две разные базы данных, чтобы получить доступ к соли и паролю с солью. Хранение их в той же таблице, что и пароль, или даже в другой таблице той же базы данных, означало бы, что когда хакеры получат доступ к базе данных, они будут иметь доступ как к соли, так и к хешу пароля. Поскольку безопасность включает в себя процесс, который делает взлом системы слишком дорогим или трудоемким, чтобы того стоить, удвоение объема доступа, который должен был бы получить хакер, должно сделать систему более безопасной.
  2. Простота использования является основной причиной хранения солей в той же базе данных, что и хешированные пароли. Вам не нужно будет гарантировать, что две базы данных всегда доступны одновременно и всегда синхронизированы. Преимущество наличия соли минимально, если у каждого пользователя есть случайная соль, потому что, хотя это может облегчить обнаружение пароля человека, количество усилий, необходимых для взлома паролей системы в целом, будет высоким. На этом уровне обсуждения это действительно то, чего ожидают: защитить пароли. Если хакеры приобрели копию базы данных, данные вашего приложения уже скомпрометированы. На данный момент проблема заключается в том, чтобы снизить риски пользователей из-за возможности использования общих паролей.
  3. Требование поддержки двух отдельных связанных баз данных является обширным. Конечно, это добавляет ощущение безопасности, но единственное преимущество, которое он дает, состоит в том, что он защищает пароль, единственный элемент данных. Если бы каждое поле в базе данных было отдельно зашифровано и для этого использовалась та же самая соль, было бы разумнее хранить его отдельно от данных, потому что базовая безопасность вашей системы улучшена.
person DaNeSh    schedule 06.12.2014
comment
Если приложение может аутентифицироваться в обеих базах данных, разве это не то же самое, что если бы это была одна база данных, если злоумышленник скомпрометировал код приложения? - person John Ernest; 17.08.2019

Суть проблемы в том, чтобы сделать все радужные таблицы бесполезными и потребовать создания нового набора из них. Чтобы угадать строку, нужно столько же времени, сколько и составить радужную таблицу. Например, хэш SHA-256 для «пароля» равен 5e88 4898 da28 0471 51d0 e56f 8dc6 2927 7360 3d0d 6aab bdd6 2a11 ef72 1d15 42d8. После добавления соли, такой как «badpassword», новая строка для хеширования будет «passwordbadpassword», которая из-за эффекта лавины резко изменит вывод на 457b f8b5 37f1 802e f9c8 2e46 b8d3 f8b5 721b 7cbb d485 f0bb e523 bfbe 73e6 58d6.

Обычно соль просто хранится в той же базе данных, что и пароль, также потому, что если одна база данных будет взломана, вполне вероятно, что другая тоже будет взломана.

person Eric Jin    schedule 24.02.2019

Причина, по которой засолка используется для предотвращения прилипания радужного стола. Злоумышленник, каким-то образом достигнув базы данных и увидев хешированные пароли, получает таблицу наиболее распространенных паролей, находит их хеш-значение и просматривает пароли в таблице.

Поэтому, когда пользователь отправляет пароль, мы добавляем к нему случайно сгенерированную соль.

 userPassword + salt

и мы передаем это нашему алгоритму хеширования.

 hash(userPassword+salt)

поскольку соль генерируется случайным образом, userPassword+salt становится случайным значением, определенно не одним из наиболее часто используемых паролей. Таким образом, злоумышленник не узнает, какой пароль использовал, проверяя радужную таблицу.

Теперь значение соли добавляется к значению хеширования, потому что оно снова используется при входе пользователя в систему для сравнения переданных учетных данных с сохраненными учетными данными.

 hash(userPassword+salt)=ashdjdaskhfjdkhfjdashadslkhfdsdh

вот как этот пароль хранится в db: ashdjdaskhfjdkhfjdashadslkhfdsdh.salt

Теперь, если злонамеренный пользователь увидит это, он сможет вычислить пароль, но это займет уйму времени. Потому что у каждого пароля будет своя соль. У Let's malware есть таблица из 5000 распространенных паролей и их хеш.

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

Теперь для каждого пароля, допустим, он начинает с пароля первого пользователя, он добавит эту соль к 5000 распространенным паролям и создаст новую радужную таблицу для каждого отдельного алгоритма, чтобы найти только 1 пароль. Тогда для пароля второго пользователя он увидит другую соль, он будет вычислять новые радужные таблицы. Даже не гарантируется, что пароль пользователя будет в списке этих общих паролей.

person Yilmaz    schedule 17.03.2021

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

С солью из 10 символов и фиксированным размером хэша в 40 символов это будет выглядеть так:

salt = "california"
passwd = "wp8tJ4Pr"

stored_passwd = salt + hash(passwd + salt)

salt = substr(stored_passwd, 0, 10)
hashed_passwd = substr(stored_passwd, 10, 40)

if hash(user_input + salt) == hashed_passwd:
    print "password is verified"

Поскольку вся цель соли состоит в том, чтобы предотвратить атаки на пароли с помощью предварительно вычисленных таблиц (например, радужных таблиц), хранение соли вместе с хешированным паролем на самом деле безвредно.

person explogx    schedule 17.05.2021