Я приведу немного другой взгляд на это.
Я всегда храню соль, смешанную с хешем соли-пароля.
Например, я помещу первую половину соли перед хешем соли, а вторую половину соли после хеша соли. Приложение знает об этой схеме, поэтому может получить эти данные и получить хэш соли и соленого пароля.
Мое обоснование для этого подхода:
Если пароль / хеш-данные скомпрометированы и попадут в руки злоумышленника, злоумышленник не будет знать, что такое соль при просмотре данных. Таким образом, злоумышленник практически не может выполнить атаку методом "грубой силы", чтобы получить пароль, соответствующий хешу, поскольку он не знает хеш с самого начала и не может узнать, какие части данных являются частями соли, или части хэша salted-пароля (, если только он не знает логику аутентификации вашего приложения ).
Если хеш с соленым паролем хранится как есть, то можно выполнить атаку методом грубой силы, чтобы получить пароль, который при солении и хешировании выдает те же данные, что и хеш соленого пароля.
Однако, например, даже если хеш-пароль с сохраненным паролем был сохранен как есть, но предварительно добавлен один случайный байт, пока злоумышленник не знает, что этот первый байт должен быть отброшен, это также увеличить сложность атаки. Ваше приложение может отказаться от первого байта данных, когда оно используется для аутентификации вашего пользователя.
Заключение к этому ..
1) Никогда не храните данные, которые ваше приложение аутентификации использует в точной форме.
2) Если возможно, держите свою логику аутентификации в секрете для дополнительной безопасности.
Пройдите еще на один шаг ..
Если вы не можете сохранить логику аутентификации вашего приложения в секрете - многие люди знают, как ваши данные хранятся в базе данных. И предположим, что вы решили хранить хэш соленого пароля, смешанный вместе с солью, причем некоторая часть соли предшествует хешу соленого пароля, а остальная часть соли добавляет его.
При генерации случайной соли вы также можете случайным образом решить, какую долю соли вы будете хранить до / после хэширования соленого пароля.
Например, вы генерируете случайную соль 512 байт. Вы добавляете соль к своему паролю и получаете хэш SHA-512 вашего соленого пароля. Вы также генерируете случайное целое число 200. Затем вы сохраняете первые 200 байтов соли, за которыми следует хеш соли с паролем, а затем остаток соли.
При аутентификации ввода пароля пользователя ваше приложение передаст строку и предположит, что первый 1 байт данных - это первый 1 байт соли, за которым следует хеш-код соли. Этот проход не удастся. Приложение будет продолжено с использованием первых 2 байтов данных в качестве первых 2 байтов соли и повторяется до тех пор, пока не будет найден положительный результат после использования первых 200 байтов в качестве первых 200 байтов соли. Если пароль неверный, приложение продолжит пробовать все перестановки, пока они не будут найдены.
Плюсы этого подхода:
Повышенная безопасность - даже если ваша логика аутентификации известна, точная логика неизвестна во время компиляции. Практически невозможно выполнить атаку грубой силой, даже зная точную логику. Увеличение длины соли еще больше повысит безопасность.
Минусы этого подхода:
Поскольку точная логика выводится во время выполнения, этот подход очень загружает процессор. Чем больше длина соли, тем интенсивнее этот процесс.
Аутентификация неверных паролей потребует максимальной загрузки процессора. Это может быть непродуктивно для законных запросов, но повышает безопасность против злоумышленников.
Этот подход может быть реализован различными способами, и его можно сделать еще более безопасным с помощью солей переменной ширины и / или хэшей с соленым паролем.