在存储用户密码的哈希值的上下文中,我对“胡椒粉”的概念感到困惑。

定义1:胡椒粉是一个秘密钥匙

环顾互联网,例如,在此处或此处,pepper通常定义为固定且随机选择的字符串,该字符串以一种或另一种方式流入哈希的计算中。主要思想是将胡椒粉与盐分开存储(通常将盐与密码哈希值一起存储在数据库中)。例如,可以将Pepper硬编码到应用程序的代码中,或在应用程序的配置中定义。

在此定义下,盐的主要区别是:


胡椒粉对所有使用者而言都是相同的。
胡椒粉与盐分开存放。

(显然,希望是因为胡椒粉存放在其他地方,因此可以提高安全性,并且使用散列和盐访问数据库的攻击者可能仍然无法访问Pepper。我不完全相信,但我不能离题。)

但是,从本质上讲,我们除了键控哈希函数以外,什么都没有说,该键称为“ pepper”。换句话说:这是一个MAC。当然,现在有很多方法可以通过加密哈希函数构造MAC,人们通常会现场提出来的那些方法通常都不好用,因此如果环顾四周,您会经常发现使用HMAC的建议(或CBC-MAC等),如果您想使用胡椒粉,那就更加清楚了,胡椒粉不过是一个秘密钥匙(例如参见此处)。

定义2:胡椒粉是未知的盐

例如,可以在此处找到的另一个定义完全不同。它指出,胡椒粉基本上是您不存储的(短的,比如说8位)随机盐。这也是我在计算机科学学习中所学到的定义,但是现在我在互联网上搜索时,发现该定义在很大程度上已经不那么普遍了。

在此定义下:


所有用户使用的胡椒粉都不同(如盐)。
根本没有储存。最初计算完密码散列后,您只需将其丢弃并忘记它(与盐不同)即可。

现在,当用户登录时,服务器必须计算28个散列(每个可能的胡椒散列一个) ),看看其中之一是否与存储的密码哈希匹配。如果可以在毫秒或更短的时间内计算出一个密码哈希,那么计算28个哈希就不是问题。但是,对于执行暴力脱机攻击的攻击者来说,这是一个问题,因为她不必为每个可能的密码计算1个哈希,而必须为每个可能的密码计算256个哈希。因此,在攻击者可能需要1天不加胡椒粉的情况下,她将需要256天不加胡椒粉。

我并不是说第二种胡椒粉比第一类胡椒粉能更好地改善安全性。我在这里看到的问题是,您不能很好地使用慢速散列函数,因为那样的话,正常的登录过程将花费很长时间,并且您不能使用快速散列函数,因为那样的话,攻击者有更大的机会遭受暴力攻击-强制散列。也许可以找到一个折衷方案,但是目前尚不清楚这是否会显着提高安全性。

问题:是否有定义辣椒的规范参考?喜欢论文还是书籍?在实践中是否使用过第二个定义?怎么会有两个根本不同的定义?即使第一个定义似乎是“典型的”定义……来……我学习时还是学到了第二个定义。它不可能完全脱胎换骨。 :)

编辑:参考文献

感谢回答者提供了启发性的解释。我从以下文献中总结了他们对辣椒的各种定义的引用:



Udi Manber。一种简单的方案,使基于单向功能的密码很难破解。 《计算机与安全》,15(2):171–176,1996年。


我们部署了两种盐,一种是公开的,另一种是秘密的。公共盐与当前盐完全相同。秘密盐类似,但有一个主要区别:类似于密码,但是与公共盐不同,秘密盐在使用后被系统丢弃。它没有保存在任何地方。 (与密码不同,不需要知道它的用户甚至不会保留它。)像公共盐一样,秘密盐是在首次输入密码时随机生成的。



Gershon Kedem和石原百合子。用
SIMD计算机对UNIX密码进行蛮力攻击。在第八届USENIX安全研讨会论文集中。 USENIX
协会,1999年。


主要思想是在密码加密中添加随机位,类似于当前用于保护密码免受字典攻击的“盐”位攻击。我们称这些新位为“辣椒”位。与使用加密密码保存的“盐”位不同,胡椒粉位用于加密密码,但从不保存。



Magnus Nystroem。 EAP保护的一次性密码协议(EAP-POTP)。
RFC 4793,RFC编辑器,2007年2月。


[降低攻击者速度的一种方法]是让客户端在哈希计算中包括攻击者未知的值(“ pepper”)。 (...)由于可以将胡椒视为MAC密钥,因此应限制其寿命。 (...)“ pepper”是一个可选的随机数(...),用于使攻击者的任务(...)复杂化。




Christian Forler, Stefan Lucks和Jakob Wenzel。 Catena:一个消耗内存的密码加扰框架。 Cryptology ePrint存档,2013/525年报告,2013年8月。<挫败对手的方法之一是保守$ p $的盐分秘密,将它们变成胡椒[Manber96] 。对手和合法用户都必须尝试辣椒所具有的所有$ 2 ^ p $值(或平均$ 2 ^ {p-1} $)。




评论

我猜胡椒的定义是您添加到密码哈希函数中的东西,而不是盐和密码。基本上我从来没有听说过选项2,并且我已经准备好消除这个愚蠢的想法,并再次将其从内存中清除。如果您使用“良好”的PBKDF函数(PBKDF2,bcrypt,scrypt),它应该已经提供了非随机的工作因子(成本,迭代次数),因此您不需要一个随机的胡椒。赌场可能喜欢赔率:P

简而言之,当涉及到密码学时,没有广泛同意使用“胡椒粉”一词。

#1 楼

我对“胡椒粉”一词的理解是,它与您的定义2更加匹配,因为胡椒粉是一种未知的盐,这使它成为密码学的秘密,而不是密钥。但是,在使用中,它不受您的两个定义的限制:


对于所有用户(例如盐),胡椒粉可以不同(或随机)。
胡椒粉对所有用户而言都可以相同(例如盐前缀)。
胡椒粉通常不与盐一起存储。
胡椒粉在哈希创建过程中始终是已知的,但在验证过程中可能是未知的。

Pepper的用途会因算法的类型而异,但是一般定义是相同的,即“对算法的其他输入保持秘密”。

在Catena中,胡椒的目的是强制执行时间参数验证,而3位胡椒的验证时间最多可能长8倍。这主要用于调整对多核处理器的验证,因此不能使用它们有效地暴力破解结果。据我所知,此定义于1999年首次使用(据我所知),它描述了缓解技术,以对UNIX系统中使用的“ crypt”功能进行暴力攻击。这符合您的定义2。RFC4793将Pepper定义为通过加密握手传输的值,该握手用于减少PBKDF2的迭代次数,同时仍保持相同的安全性。解密后,将其附加到盐中。他们将其描述为“可选的随机数”和“ MAC密钥”,但是它们的正式定义是“哈希计算中攻击者未知的值”,而不是一次性密码。它存储在客户端设备和服务器上,并根据长度和安全要求在必要时进行替换。

几种系统都使用胡椒粉作为盐的前缀或后缀。使用该算法的每个系统都不同,因此,盐和密码的相同组合会导致不同的哈希。在实现中,我看到了Pepper不是存储在数据库中,而是存储在算法使用的配置文件中,或者编译到程序本身中。在这种情况下,对数据库的管理员访问权无法访问Pepper,因此对数据库是秘密的,但对具有文件系统访问权的人则不是秘密的。我使用术语“服务器盐前缀”代替胡椒。这与您的定义1非常接近。

一些算法已被修改为通过将值附加到密码来添加值。在这种情况下,该算法通常对密码长度有一些预设限制,这有利于密码熵,因为长密码可能会截断该值。我还看到使用该值作为新的盐值再次哈希的哈希函数的输出。在某些情况下,当描述修改时,此值被称为“ pepper”。

我已经看到Pepper被定义为程序的已知和未知,但假定为攻击者未知。我已经看到Pepper被定义为另一个算法输入的前缀以及唯一输入。我从未见过将胡椒严格定义为任何加密密钥材料。无论目的是什么,“在保密的算法的额外输入”之上似乎都没有明确的定义。对于更严格的定义(在我看来),如何添加输入以及如何对其保密(以及如何保密)(我认为)。

评论


$ \ begingroup $
谢谢,这是一个很好的答案。我同意您对胡椒的一般定义,这很合情合理。
$ \ endgroup $
–马尔特·斯科鲁帕(Malte Skoruppa)
2014年12月2日21:32

$ \ begingroup $
使用“未知盐”防御多核计算机似乎不是一个有用的策略-攻击者仍然可以使用不同的盐来利用其所有内核进行暴力破解。 (而且实际验证者还需要猜测正确的盐。)
$ \ endgroup $
–PaŭloEbermann
16年7月24日在15:25

$ \ begingroup $
@PaŭloEbermann,实际验证者设置了胡椒粉的大小,以便他们可以并行利用所有核,同时花费的时间就好像它们只有1核而没有胡椒。如果验证者有8个核心,而攻击者有80个核心,则强力攻击只需要1/10的时间,而不是时间的1/80
$ \ endgroup $
– Richie车架
16年7月25日在19:54

#2 楼

从Catena纸的版本2开始。

盐是指密码加扰器的另一个随机输入值,与密码哈希一起存储。它使密码加扰器能够从单个密码中衍生出许多不同的密码哈希,就像初始化向量一样,使加密方案能够从单个纯文本中衍生出许多不同的密文。由于必须随机均匀地选择盐,因此不同的用户很有可能会使用不同的盐。因此,它会阻止攻击者知道来自许多不同用户的密码哈希的攻击,例如,阻止使用彩虹表[40]。
请注意,还有其他方法可以阻止攻击者,即执行攻击的方法关键伸展。一种方法是将p盐的一部分保密,将其变成胡椒[34]。对手和合法用户都必须尝试胡椒可以具有的所有$ 2 ^ p $值(或平均$ 2 ^ {p-1} $)。请注意,当以特定顺序尝试所有可能的值时,这种方法的粗心实现可能会通过时序信息泄漏胡椒的一些位。因此,更好的方法是从一个随机值开始并以$ 2 ^ p $环绕。 Kelsey等。 [28]分析了另一种密钥扩展方法,其中加密操作被迭代$ n $次,其中$ n $是秘密的。 Boyen在[9]中提出了$ n $的用户定义的隐式选择,方法是迭代直到用户按下“暂停”按钮。

请注意,Catena还引入了“大蒜”的概念,值以调整哈希函数的内存消耗。这不是一个广泛使用的标准。

评论


$ \ begingroup $
谢谢,这是一个很好的参考。 (顺便说一句,您的链接似乎指向该论文的其他版本,其中不包括您的报价。ePrint版本中确实包含该报价。)另一个很好的引用是该引用中的[34]引用,该论文是由YouTube当前的工程副总裁Udi Manber。我在问题末尾总结了这些(和其他回答者的)参考文献。
$ \ endgroup $
–马尔特·斯科鲁帕(Malte Skoruppa)
2014年12月2日21:30