Существует ли идемпотентная хэш-функция?

Существует ли идемпотентная хэш-функция? Я знаю, что MD5 и SHA256 не являются:

$ echo -n "hello world" | md5sum
5eb63bbbe01eeed093cb22bb8f5acdc3  -
$ echo -n "5eb63bbbe01eeed093cb22bb8f5acdc3" | md5sum
c0b0ef2d0f76f0133b83a9b82c1c7326  -

$ echo -n "hello world" | sha256sum
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9  -
$ echo -n "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9" | sha256sum
049da052634feb56ce6ec0bc648c672011edff1cb272b53113bbc90a8f00249c  -

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

$ echo -n "hello world" | idempotentsum
abcdef1234567890
$ echo -n "abcdef1234567890" | idempotentsum
abcdef1234567890

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

Если такого алгоритма не существует, значит ли это, что его не существует потому, что его никто не удосужился найти, или это математическая невозможность?

Контекст

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

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

РЕДАКТИРОВАТЬ: я не утверждаю, что разрешение пользователю аутентифицироваться с помощью хешированного пароля означает, что сервер может не солить/хешировать пароль. Сервер должен по-прежнему солить/хешировать исходный пароль или хешированный пароль на стороне клиента.

РЕДАКТИРОВАТЬ: я не утверждаю, что разрешение пользователю входить в систему с хешированным паролем на стороне клиента является настоящим улучшением безопасности. Насколько я знаю, единственное возможное преимущество, которое это добавит, - это если пользователь использовал этот пароль более чем для одной цели. В этом случае, если злоумышленник обнаружит хешированный пароль пользователя, то будет скомпрометирован только доступ к моей службе, а не ко всем службам, использующим этот пароль. Однако рекомендуется не использовать один и тот же пароль для нескольких служб.


person phylae    schedule 25.04.2015    source источник
comment
я не думаю, что пользователь, который хочет сохранить хешированный пароль, параноик   -  person Krab    schedule 25.04.2015
comment
@AndrewMedico: Википедия говорит: Идемпотентность (/ˌaɪdɨmˈpoʊtəns/EYE-dəm-POH-təns) — это свойство определенных операций в математике и информатике, которое можно применять несколько раз без изменения результата после первоначального применения.< /i> Я думаю, что это определенно правильное слово здесь.   -  person Marcus Müller    schedule 25.04.2015
comment
Пользователи, сохраняющие пароли на своей стороне в хешированной форме, бессмысленны. Если сервер принимает определенную строку для входа в систему, это по определению пароль в виде открытого текста. Неважно, случайное это слово или результат хеша. На самом деле это намного хуже для безопасности, потому что, если кто-то когда-либо получит копию базы данных входа в систему (скажем, может быть, потерянный резервный диск), он может немедленно войти в систему как любой пользователь, не утруждая себя взломом хэшей.   -  person nobody    schedule 26.04.2015
comment
@Krab Я не использую термин «параноик» для обозначения чего-то плохого. Вместо этого я мог бы использовать фразу о безопасности. Но я думаю, что пользователь, заботящийся о безопасности, знает, что нужно использовать уникальный пароль для каждого веб-сайта. Насколько мне известно, это сводит на нет все преимущества хеширования пароля на стороне клиента.   -  person phylae    schedule 26.04.2015
comment
@AndrewMedico Я не утверждаю, что хеширование пароля на стороне клиента устраняет необходимость повторного хеширования пароля на стороне сервера. Серверу обязательно нужно солить/хешировать пароль. Я согласен, что в этом случае у пользователя фактически есть два пароля. Единственный смысл в хешировании пароля на стороне клиента — если пользователь делится этим паролем с другими службами (что, конечно, плохая идея). Я предоставил контекст, чтобы лучше объяснить, как я пришел к этому вопросу. На самом деле я не верю, что это хороший вариант использования алгоритма, который я ищу. Я отредактирую, чтобы сделать это более понятным.   -  person phylae    schedule 26.04.2015
comment
Я думаю, что это мой первый вопрос с отрицательным голосованием. Может ли кто-нибудь предложить улучшение? Должен ли я исключить раздел контекста, потому что он не имеет отношения к делу? Должен ли я публиковать сообщения на другом сайте (возможно, crypto.stackexchange.com)?   -  person phylae    schedule 28.04.2015
comment
Вероятно, за нее проголосовали за схему аутентификации с очевидными и вопиющими уязвимостями, которые не следует реализовывать.   -  person inopinatus    schedule 04.01.2020


Ответы (2)


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

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

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

person Jared Windover-Kroes    schedule 07.08.2018

Если такой алгоритм существует, полезен ли он с точки зрения криптографии?

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

A -> B

где B — множество возможных хэшей, а A — множество вещей, которые можно хэшировать.

Теперь обычно A намного больше, чем B — хэши подобны более коротким «контрольным суммам», которые можно вычислить из гораздо больших потоков данных. Как правило, вы все равно хотите, чтобы в вашем хеше было как можно меньше коллизий, а это означает, что статистически все элементы из B должны иметь одинаковое количество элементов из A, которые сопоставляются с ними, и элементы из A, которые сопоставляются с одним и тем же элементом в B должны быть «далеко» друг от друга по какой-то метрике. Это означает, что B изо всех сил старается быть целым набором слов постоянной длины. Будет невероятно сложно найти систематическую функцию, которая делает это, но при этом отображает каждый элемент из B в тот же самый элемент в B; вы «принуждаете» столкновение. В общем, это криптографическая слабость, причем серьезная.

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

person Marcus Müller    schedule 25.04.2015
comment
Я согласен с тем, что аутентификация на основе ключей (например, SSH) лучше, чем использование паролей. Но почти каждый веб-сайт в наши дни позволяет пользователям аутентифицироваться с помощью простого текста пароля, включая большинство онлайн-банков. Я так же недоволен, как и любой другой человек, отсутствием принятия сертификатов SSL на стороне клиента. Но я подозреваю, что причина в том, что копирование клиентских ключей на каждое устройство — это слишком много, чтобы ожидать от обычного веб-пользователя. - person phylae; 26.04.2015