使用NP进行密码散列的完整问题


16

如今,常用的密码哈希算法的工作方式如下:对密码加盐并将其输入到KDF中。例如,使用PBKDF2-HMAC-SHA1,密码哈希处理为DK = PBKDF2(HMAC, Password, Salt, ...)。因为HMAC是带有填充键的2轮哈希,而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。那么8个子句中只有1个为false(第一个)。如果我们丢弃第一个子句,而与AND其余7个子句一起丢弃,则000是所得公式的解决方案。因此,如果我们存储公式,则可以验证000。

问题是,对于一个3位的字符串,如果您在其中看到7个不同的子句,那么您会立即知道缺少哪个子句,而这将揭示这些位。

因此,后来我决定放弃其中的3个,只保留标记为001、010、100和111的4个。这有时会引入冲突,但解决问题的难度却很小。冲突并不总是发生,但是尚不清楚当输入的位数更多时,冲突是否会消失。

编辑。在通常情况下,二进制字符串可以是(000,001,...,111)中的任何一个,仍然有8个子句,其中7为true,1为false。选择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),这意味着hash是密码大小的多项式。

有Python中的原型实现在这里。它根据用户输入的二进制字符串生成3-SAT问题实例。


经过漫长的介绍,最后我的问题是:

  1. 上述构造(在原型中实现)是否可以用作安全密码哈希,或者至少看起来很有希望,可以进行修改等?如果没有,它在哪里失败?

  2. 因为我们有7 * C(n,3)子句可供选择,是否有可能找到另一种方法来构造适合用作密码哈希的安全3-SAT实例,可能需要借助随机化?

  3. 是否有任何类似的工作试图利用NP完整性来设计经过验证的安全密码哈希方案,并且已经取得了一些成果(肯定或否定)?一些介绍和链接将非常受欢迎。


编辑。我会接受@DW的以下回答,他是第一个回答并提供了有关问题结构以及有用资源的深刻见解。这里引入的朴素的子句选择方案(在Python原型中实现)似乎没有用,因为可以快速缩小小组中的变量分配范围。但是,问题仍然存在,因为我还没有看到正式的证据表明这种减少NPC-to-PasswordHashing的方法根本行不通。即使对于这个特定的3-SAT归约问题,选择子句的方式也可能有不同的方式,在此我不想一一列举。因此,仍然非常欢迎任何更新和讨论。


在这里将生成的子句插入了sat求解器(使用pycosat的picosat)。对于nbits = 300,最长的是生成子句,pycosat杀死实例。我没有超过300,因为您的子句生成实际上很长。同样,0 ... 0 始终是您这一代的解决方案。如果您始终有这样的“简单”解决方案,那么它将无法正常工作。
Holf

Answers:


17

不幸的是,这似乎不起作用(有关详细信息,请参见下文),并且似乎很难找到一种方法来使这种想法产生可证明的安全方案。

您的总体思路存在问题

您不是第一个想到尝试将密码学基于NP完全问题的想法的人。问题在于,NP硬度仅确保最坏情况的硬度,而密码术则需要平均情况下的硬度。已经进行了多次尝试使密码学基于NP完全问题(例如背包密码系统),但是进展并不顺利。通常,发生的事情是人们发现算法通常在平均水平(或具有不小的概率)下有效,即使在最坏的情况下它们是指数级的;即使它与NP硬度没有矛盾,也足以破坏加密。

我建议阅读更多有关该主题的信息。您可以在以下方面找到一些有用的起点:“密码学中的NP硬问题的重要性”,“ 单例函数以外的平均情况下的复杂性开放问题”“ Impagliazzo的世界状况?”。最坏情况减少到平均情况

您的特定方案存在的问题

您的具体提案未完全指定。要分析方案,您需要完全指定方案的工作方式。在您的情况下,尚不清楚如何在一般示例的7个子句中选择4个。(而且,一个示例不能代替描述您通常如何操作的规范。)

X0X1个X2X3X425这5个变量的可能赋值,因此请全部尝试并丢弃40子句中的任何违反的赋值。我预计这将使您只剩下与所有子句都一致的一项赋值。

1个/21个/21025-1个7/87/8402-7.725-1个×2-7.70.15

可以对每组5个变量重复此操作,从而唯一地恢复每个变量的唯一令人满意的分配。如果有任何歧义,可以对照其他子句检查候选分配。

这样,我们看到有一种有效的算法通常可以解决您的过程生成的3SAT实例的类。它不会解决所有3SAT实例,但是生成的实例具有特殊的结构,并且可以有效地解决具有该特殊结构的实例。这很好地说明了这一点:3SAT的某些实例比其他实例更容易,并且3SAT的硬度(在最坏的情况下)对生成的特殊实例的硬度或平均3SAT实例的硬度几乎没有说什么。


有一个参考实现可作为完整规格。在第一次尝试中,该方案非常简单。我简单地选择了4个子句,当替换密码时将给出001、010、100和111。每个子句给出8个有效组合中的4个。
Cyker

您可能是正确的,尽管此快速给出了太多的子句,这使快速缩小解决方案范围成为可能。但是,我们从O(n ^ 3)子句开始,我们可以自由选择保留哪个子句。三胞胎可能不是独立的。因此,我想知道是否以尝试删除简单问题实例的模式选择了子句,您的启发式分析是否仍然有效。
Cyker

1
但是,更有趣的是,粗略地说,我们没有任何一般情况的NPC问题吗?
Cyker

1
@Cyker,你绝对正确。严格来说,您不能将这些概率相乘,因为不能保证这些概率是独立的。这只是一种尝试,试图预测算法的效果。启发式可能是错误的。最终测试是实施算法,并查看其是否有效。
DW

2
一种快速的测试可能是在SAT求解器上尝试您的实例。我认为SAT解算器将对您的实例有效,但是我并未完全尝试理解您的规范。尝试生成10000个变量实例并运行SAT解算器(顺便说一下,如果不进行填充/填充,则密码会小得多...)
Holf
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.