Рейтинг:2

Какая хеш-функция подходит для идентификаторов сеансов?

флаг br

Задний план

Я создаю средство сокращения URL-адресов, и URL-адрес для сокращения может содержать Идентификатор сессии.

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

OWASP заявляет, что:

  • Длина идентификатора сеанса должна быть не менее 128 бит (16 байт) здесь
  • Значение идентификатора сеанса должно содержать не менее 64 бита энтропии здесь

Что я думаю о том, чтобы сделать

  • Иметь хранилище ключей и значений, где значением является длинный (несокращенный) URL-адрес, а ключом является сокращенный компонент URL-адреса.
  • Когда пользователь переходит по сокращенному URL-адресу, длинный URL-адрес ищется в хранилище ключей и значений и возвращается пользователю, который затем перенаправляется.

Таким образом, ключ должен быть как минимум 128 бит (16 байт) длинной и предоставить не менее 64 бита энтропии, чтобы не скомпрометировать SessionId.

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

Но какой алгоритм хеширования мне следует использовать?

Например, длина дайджеста MD5 составляет ровно 128 бит. Но я не знаю, что такое минимальная энтропия.

Вопрос

Какой алгоритм хеширования производит дайджест размером не менее 128 бит с энтропией не менее 64 бит?

(х-пост из StackOverflow: https://stackoverflow.com/q/71224441/6517320)

kelalaka avatar
флаг in
Не могли бы вы сохранить одну копию вашего вопроса? Подробности см. в разделе [Разрешена ли перекрестная публикация вопроса на нескольких сайтах Stack Exchange, если вопрос актуален для каждого сайта?](https://meta.stackexchange.com/q/64068/403350).
kelalaka avatar
флаг in
Обратите внимание, что энтропия не является свойством значения/данных, это свойство источника.Получите равномерный случайный размер 64-битного размера, хешируйте его и усеките до 128-битного. Используйте BLAKE2 в качестве самого быстрого криптографического хеширования, хотя вам не нужно...
Рейтинг:5
флаг cn

Краткий ответ на ваш вопрос о хешировании: «используйте SHA-256». Это ответ практически для любой проблемы с безопасным хешированием, если только ответ не «используйте SHA-512». Если вам нужен 128-битный хэш, вы можете обрезать SHA-256 (взять первые или последние 128 битов). Все биты в SHA-256 независимы, поэтому вы можете извлечь любые 128 из них как хэш.

Тем не менее, ИМО, вы неправильно думаете об этой проблеме. Дело не в защите SessionId конкретно.Проблема в том, что URL-адреса могут содержать конфиденциальную информацию, одним из примеров которой является SessionId (если он хранится в URL-адресе). Если кто-то уже знает сокращенный URL-адрес, он может просто запросить у вашей системы полный URL-адрес, так что это все для того, чтобы злоумышленники не могли найти ключи путем угадывания. Вам нужно сделать ваше пространство ключей разреженным, то есть сказать «намного, намного больше, чем количество фактически сохраненных ключей».

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

Учитывая ваш дизайн, злоумышленники не могут осуществлять поиск в автономном режиме. Они должны связаться с вашим сервером. Скажем, вы можете обслуживать 1000 запросов в секунду и масштабируете общее пространство ключей так, чтобы оно в триллион раз превышало запланированное количество URL-адресов. Злоумышленнику потребовалось бы примерно 15 000 лет (~ 1/2 поискового пространства), чтобы найти один URL-адрес, если бы они могли использовать всю доступную пропускную способность (что, я ожидаю, вы могли бы заметить....). С небольшим ограничением скорости для каждого IP-адреса вы можете значительно усложнить эту атаку.

Учитывая вышеизложенное, если вы хотите хранить миллиард URL-адресов в своей системе, вам понадобится пространство ключей:

log2 (1 миллиард URL * 1 триллион множителя) = 80 бит

В Base58 (который мне нравится для такого рода задач, потому что он удобен для человека) это заняло бы около 14 символов. Изменяя приведенные выше значения для ограничения скорости, периода атаки, от которой вы хотите защитить, и количества сохраненных URL-адресов, вы можете выбрать длину ваших ключей.

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

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

Ivan Rubinson avatar
флаг br
Как это гарантирует не менее 64 бит энтропии?
флаг cn
Это зависит от вашего PRNG. В системах Linux, если вы используете /dev/random, я полагаю, что он заблокируется, если система упадет ниже 160 бит доступной энтропии, поэтому вы всегда должны быть в порядке в такой системе. Я ожидаю, что любая система, в которой вы используете криптографический PRNG, будет значительно превышать 64 бита для каждого значения, но вам придется проверить свою документацию, чтобы быть уверенным. Например, на некоторых (но не на всех) системах /dev/urandom будет возвращать значения с низкой энтропией.
флаг cn
Но никакая хеш-функция не может увеличить энтропию, и если они устойчивы к коллизиям в рассматриваемом пространстве, они не будут (эффективно) уменьшать энтропию. Энтропия исходного SessionId будет сохранена любым криптографическим хешем. Если изначально у него было меньше 64 бит, то и хеш будет таким же, а если у него было больше 64 бит, то будет и хеш (минус немного). Чтобы увеличить энтропию, вы должны добавить случайную соль, что означает, что вы привязаны к энтропии вашего PRNG (точно так же, как при использовании случайного ключа). https://crypto.stackexchange.com/questions/12505/what-happens-to-entropy-after-hashing
Ivan Rubinson avatar
флаг br
Таким образом, энтропия хеша = энтропия открытого текста. Следовательно, чтобы обеспечить достаточную энтропию, открытый текст должен иметь высокую энтропию. Длинный URL-адрес имеет низкую энтропию, в отличие от криптографически стойкой псевдослучайной строки байтов; поэтому вы рекомендуете, чтобы ключ не был хэшем длинного URL-адреса.
флаг cn
Близко, но энтропия хэша никогда не превышает энтропию открытого текста. Устойчивые к коллизиям хэши просто меньше уменьшают энтропию (как правило, на незначительную величину). В остальном ваш комментарий верен.
Ivan Rubinson avatar
флаг br
Простите за путаницу в обозначениях. Если `A = B`, то `A > B` невозможно. Поскольку хеширование не может увеличить энтропию, но может уменьшить энтропию, мы не выиграем от хэширования, а только потеряем.
SAI Peregrinus avatar
флаг si
«В системах Linux, если вы используете /dev/random, я полагаю, что он заблокируется, если система упадет ниже 160 бит доступной энтропии». Это не так уже некоторое время. Не то, чтобы это имело значение, но он блокируется только при ранней загрузке и больше никогда. Энтропия не "израсходована", поэтому блокировка после раздачи никогда ничему не помогала.
флаг cn
Спасибо @SAIPeregrinus. Я давно не был системным администратором Linux :D У вас есть какие-нибудь ссылки на текущее состояние дел в Linux, чтобы я мог лучше узнать? (Мой криптографический мозг абсолютно понимает, что вы имеете в виду; я просто хочу, чтобы моя сторона системного администратора понимала, что происходит на практике.)
kelalaka avatar
флаг in
[Какие проблемы возникают при использовании Linux /dev/urandom для генерации криптографических ключей?](https://crypto.stackexchange.com/q/85533/18298)
SAI Peregrinus avatar
флаг si
Также см. [эту статью LWN] (https://lwn.net/SubscriberLink/884875/650dde925be055a1/) о предложенном патче для унификации поведения /dev/random и /dev/urandom и getrandom(flags=0).
Ivan Rubinson avatar
флаг br
Много говорят о том, как Linux обрабатывает CSPRNG. Как насчет Windows?

Ответить или комментировать

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