Хеширование паролей с использованием проблем с NP

16

Обычно используемые алгоритмы хэширования паролей работают сегодня так: солить пароль и подавать его в KDF. Например, используя PBKDF2-HMAC-SHA1, процесс хеширования пароля DK = PBKDF2(HMAC, Password, Salt, ...). Поскольку HMAC представляет собой двухэтапное хеширование с дополненными клавишами, а SHA1 - последовательность перестановок, сдвигов, вращений и побитовых операций, по сути, весь процесс представляет собой некоторые базовые операции, организованные определенным образом. По сути, не очевидно, насколько сложно их вычислить. Вероятно, поэтому односторонние функции все еще верят, и мы видели, как некоторые исторически важные криптографические хеш-функции стали небезопасными и устарели.

Мне было интересно, можно ли по-новому использовать комплексные задачи NP для хеширования паролей, надеясь дать ему более прочную теоретическую основу. Ключевая идея состоит в том, что P! = NP (если P == NP, тогда нет OWF, поэтому текущие схемы тоже ломаются), поскольку проблема NPC означает, что ответ легко проверить, но сложно вычислить. Это свойство хорошо согласуется с требованиями хеширования паролей. Если мы рассматриваем пароль как ответ на проблему NPC, то мы можем сохранить проблему NPC как хэш пароля для противодействия атакам вне сети: пароль легко проверить, но взломать сложно.

Предостережение заключается в том, что один и тот же пароль может быть сопоставлен с несколькими экземплярами проблемы NPC, вероятно, не все из них трудно решить. В качестве первого шага в этом исследовании я пытался интерпретировать двоичную строку как ответ на проблему 3-SAT и построить экземпляр проблемы 3-SAT, для которой двоичная строка является решением. В самой простой форме двоичная строка имеет 3 бита: x_0, x_1, x_2. Тогда есть 2 ^ 3 == 8 предложений:

000 (    (x_0) v    (x_1) v    (x_2) )
--------------------------------------
001 (    (x_0) v    (x_1) v NOT(x_2) )
010 (    (x_0) v NOT(x_1) v    (x_2) )
011 (    (x_0) v NOT(x_1) v NOT(x_2) )
100 ( NOT(x_0) v    (x_1) v    (x_2) )
101 ( NOT(x_0) v    (x_1) v NOT(x_2) )
110 ( NOT(x_0) v NOT(x_1) v    (x_2) )
111 ( NOT(x_0) v NOT(x_1) v NOT(x_2) )

Предположим, что двоичная строка равна 000. Тогда только 1 из 8 предложение является ложным (первое). Если мы отбрасываем первое предложение и И остальные 7 предложений, то 000 является решением полученной формулы. Так что, если мы храним формулу, то мы можем проверить 000.

Проблема в том, что для 3-битной строки, если вы видите там 7 различных предложений, вы сразу узнаете, какой из них отсутствует, и это выявит биты.

Позже я решил отбросить 3 из них, оставив только 4, отмеченные 001, 010, 100 и 111. Это иногда приводит к столкновениям, но делает решение задачи менее тривиальным. Столкновения не всегда случаются, но неизвестно, исчезнут ли они, когда на входе будет больше битов, пока неизвестно.

Редактировать. В общем случае, когда двоичная строка может быть любой из (000, 001, ..., 111), все еще есть 8 предложений, где 7 - истина, а 1 - ложь. Выберите 4 предложения, которые дают значение истинности (001, 010, 100, 111). Это отражено в реализации прототипа ниже.

Редактировать. Как показано в ответе @DW ниже, этот метод выбора предложений может по-прежнему приводить к слишком большому количеству предложений в данном наборе переменных, что позволяет быстро сузить их значения. Существуют альтернативные способы выбора предложений среди общих предложений 7 * C (n, 3). Например: выберите другое количество предложений из данного набора переменных и делайте это только для смежных переменных ((x_0, x_1, x_2), (x_1, x_2, x_3), (x_2, x_3, x_4), .. .) и, таким образом, образуют цикл вместо клики. Этот метод, вероятно, не работает, потому что интуитивно вы можете попробовать присвоения, используя индукцию, чтобы проверить, все ли условия могут быть выполнены. Итак, чтобы было проще объяснить общую структуру, давайте просто используем текущий метод.

Количество предложений для n-битной строки равно 4 * C (n, 3) = 4 * n * (n - 1) * (n - 2) / 6 = O (n ^ 3), что означает размер хеш - это полином от размера пароля.

Там есть реализация прототипа в Python здесь . Он генерирует экземпляр проблемы 3-SAT из двоичной строки ввода пользователя.


После этого длинного вступления, наконец, мои вопросы:

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

  2. Поскольку у нас есть 7 * C (n, 3) предложений, можно ли найти другой способ создания защищенного экземпляра 3-SAT, пригодного для использования в качестве хэша пароля, возможно, с помощью рандомизации?

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


Редактировать. Я бы принял ответ @DW, который первым ответил на него и дал отличное представление о структуре проблемы, а также о полезных ресурсах. Представленная здесь схема выбора наивного предложения (реализованная в прототипе Python), похоже, не сработала, поскольку можно быстро сузить назначения переменных в небольших группах. Однако проблема остается открытой, потому что я не видел формальных доказательств того, что такие сокращения NPC-to-PasswordHashing не будут работать вообще. Даже для этой конкретной проблемы сокращения 3-SAT могут быть разные способы выбора предложений, которые я не хочу перечислять здесь. Так что любые обновления и обсуждения по-прежнему очень приветствуются.

Cyker
источник
Я подключил генерацию вашего предложения к спутниковому решателю (picosat, используя pycosat) здесь . Для nbits = 300 самое длинное - генерировать предложения, pycosat убивает экземпляр. Я не прошел более 300, потому что ваше предложение на самом деле очень долго. Кроме того, 0 ... 0 всегда является решением для вашего поколения. Если у вас всегда есть такие «простые» решения, то это не сработает.
Холф

Ответы:

17

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

Проблема с вашей общей идеей

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

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

Проблема с вашей конкретной схемой

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

Икс0,Икс1,Икс2,Икс3,Икс425возможные присвоения этим 5 переменным, поэтому попробуйте их все и откажитесь от любого присвоения, которое нарушается любым из 40 предложений. Я предсказываю, что это даст вам только одно назначение, которое согласуется со всеми пунктами.

1/21/21025-17/8(7/8)4027.7(251)×27.70,15

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

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

DW
источник
Существует эталонная реализация, которая действует как полная спецификация. В этой первой попытке схема действительно проста. Я просто выбрал 4 предложения, которые дали бы 001, 010, 100 и 111 при подстановке в пароле. Это дает 4 действительные комбинации из 8 для каждого предложения.
Cyker
Вы, вероятно, правы в том, что это быстрое предложение дает слишком много предложений, что позволяет быстро сузить решение. Тем не менее, мы начинаем с O (n ^ 3) предложений, и мы можем выбирать, что оставить. Триплеты не могут быть независимыми. Поэтому мне интересно, будут ли предложения выбраны с шаблоном, который пытается удалить простые проблемные экземпляры, остается ли ваш эвристический анализ все еще в силе.
Cyker
1
Но что самое интересное, грубо говоря, у нас нет проблем с NPC в среднем случае?
Cyker
1
@ Cyker, ты абсолютно прав. Строго говоря, вы не можете умножать вероятности, поскольку нет никаких гарантий, что вероятности независимы. Это просто эвристика, чтобы попытаться предсказать, насколько хорошо алгоритм может работать. Эвристика может быть неправильной. Окончательный тест - реализовать алгоритм и посмотреть, работает он или нет.
DW
2
Одним из быстрых тестов может быть проверка ваших экземпляров на SAT-решателе. Я думаю, что SAT Solvers будет эффективен в ваших случаях, но я не полностью пытался понять вашу спецификацию. Попробуй сгенерировать экземпляр 10000 переменных и запустить SAT Solver (кстати, без дополнения / засолки пароли будут намного меньше ...)
holf