Здравствуйте, #John, Вы писали:
Сразу замечание по терминологии.
В криптографии сейчас принято для такого применения говорить не
"соль", а
"перец". Соль открыта, а перец засекречен, в этом принципиальная разница.
Дальше в ответе буду называть таки перцем.
J>Здравствуйте,
J>Есть функция, которая берет от данных xor солью — sha256 хеш.
Тут vsb правильный вопрос задал — что будет, если данных 1 байт?
Если xor выполняется с такой же длиной перца, как данные (предположим, что перец в принципе неограниченной длины) — то от него будет работать тоже 1 байт, и на вход sha подастся 1 байт.
Это значит, взломщик может проверить 256 возможных значений этого перца и найти первый байт (со смещением 0).
Зная первый байт, он может сделать точно так же 256 проверок на второй байт и найти его. И так далее.
Это очень древняя ошибка (была совершена на древнем SMB середины 90-х... мне помнятся слова NTLM hash, но не помню, это дырявый вариант или уже исправленный).
Поэтому если используется такой метод (который туповат сам по себе), то вводимое надо удлинять и передавать в хэшер сразу длинную порцию. Нормально сейчас — не менее 20 байт, лучше — 32 или 64.
Как именно удлинять — по обстановке. Можно начать с добивания хвоста нулевыми байтами до нужной длины. Можно вначале передавать байт длины. Рандомизация, увы, недопустима по условию, как я понял.
J>Пользователь может сколько угодно раз вызывать эту функцию и он знает какие данные передает в функцию и знает какой получает в ответ хеш,
J>но не знает какая соль используется внутри функции.
J>Насколько легко пользователю будет узнать соль.
При нормальной защите — нелегко. Но через XOR, насколько я знаю, защита не нормальная.
Даже дописать перец в конец строки перед хэшированием — уже эффективнее и не имеет проблем, описанных выше (что перец надо урезать для короткой входной строки или повторять для длинной).
Ещё есть методы, например, делать ключ из конкатенации входной строки и перца, и шифровать им какие-то данные (можно константную последовательность, можно ту же суммарную строку), использовалось в некоторых версиях юниксовой crypt() (хоть и для соли).