【问题标题】:Is there an advantage to this hash for security?这个散列对安全性有好处吗?
【发布时间】:2011-06-12 04:32:32
【问题描述】:

有什么好处

sha1(sha1(sha1($password. $salt)));

基本上有多个 sha1 诗句只有一个 sha1

sha1($password. $salt);

【问题讨论】:

  • 如果您的$salt 强大、较长且字符随机混合,则后者就足够了。基本上,只有当有人用你的盐编译彩虹表时,后者才容易受到攻击,如果你的$salt 足够强大,例如。 12@!(*E&HD*&@#HE!_)UDJNuyhdsbq897cuddaadn*&BD#NXUHSD8uyahs... 在我看来,使用多个 sha1 会更安全一些。
  • 谢谢。我正在使用强盐。
  • 相关问题有一些很好的信息和对话:Many Hash Iterations, append salt every time?

标签: php security hash sha1


【解决方案1】:

不要,我再说一遍,不要试图通过做“特殊”的事情来使您的密码哈希更安全。

首先,sha1(sha1(sha1($input))) 仅在每次迭代时增加碰撞机会* 的副作用。增加碰撞的机会是一件非常糟糕的事情。

与其尝试自己动手做密码学,不如相信由该领域的实际专家制作的库?使用Portable PHP password hashing framework

PHPass 实际上使用了bcrypt,这是一种旨在防止彩虹表、字典和暴力破解攻击的算法。您可以使用多轮对其进行初始化:轮数越高,计算散列所需的时间越长。这样一来,如果处理能力提高,您就可以创建更强的哈希值。


*sha1() 的第一次调用采用无限输入并从2160 输出中创建一个。第二次迭代采用2160 输入并从x 输出中创建一个,其中x <= 2160。第三次迭代采用x 输入并从y 输出中创建一个,其中y <= x <= 2160

为什么每次调用sha1() 都会减少可能输出的数量?因为sha1() 背后的算法不是为哈希的一对一匹配而设计的。从理论上讲,如果你要散列所有可能的散列,你肯定会发生冲突。

【讨论】:

  • phpAss 本身使用多次迭代进行哈希处理(只看第一种方法),这是一个很好的安全实践。
  • @Alex Axel:在便携模式下,是的。但是,它总是重新散列与密码 (sha1($hash . $password)) 连接的前一个哈希值,将可能的输入保持为无限,因此不会增加冲突的机会......通常,$password 是无限输入的唯一来源,除非您使用每个哈希$salt.
  • @Andrew Moore:您的论点存在谬误,bcrypt 与 sha1 有 相似 的冲突机会 - 两者都被多次重新散列。
  • @Alix:没有。调用sha1(...sha1($f00)) 将会减少碰撞次数。要了解原因,我们将其命名为 A(B(C($foo)))。现在,我们知道C 会在无穷大 > 2^256 后发生碰撞。因此,C 的所有冲突都会自动成为 A 和 B 的冲突,因为输入没有被修改。 B and A. So the total collisions are much more than for C` 也是如此。但是,如果您使用A(B(C($foo) . $foo) . $foo),它的碰撞次数与C 完全相同...
  • @Alix Axel:bcrypt 实际上并没有对密码进行任何迭代。 bcrypt 迭代初始化向量并对其进行多次转换,以便使用结果向量创建散列。在基本术语中,它会多次转换“盐”(IV),直到它在密码学上足够安全,可以使用它生成散列。要将输入与 bcrypt 散列进行比较,您需要存储的散列以提取原始 IV(存储在散列中,每个唯一),让 bcrypt 再次转换向量,散列原始输入,然后比较两者产生的哈希值。
【解决方案2】:

是的,这被称为key strengthening(但通常会执行数千次),并且应该在每次迭代中添加盐以获得更好的熵:

$hash = sha1($password . $salt);

for ($i = 1; $i <= 65000; ++$i)
{
    $hash = sha1($hash . $salt);
}

另外,read this awesome blog post - 或者至少是这个简短的引用:

您可以更好地优化您的 密码哈希函数,越快 你的密码哈希函数得到, 你的计划较弱。 MD5 和 SHA1, 甚至像传统的分组密码 DES,旨在快速。 MD5, SHA1 和 DES 是弱密码 哈希。在现代 CPU 上,原始加密 像 DES 和 MD5 这样的构建块可以 被位切片、矢量化和 并行化以进行密码搜索 闪电般的快。游戏结束 FPGA 实施成本仅数百 美元。

使用原始散列函数来验证密码是幼稚的 使用未加盐的哈希函数。 不要。

这里的最新技术是什么?

首先,您的操作系统是什么 已经给你了:一个密码方案 “优化”以进行计算 昂贵的。其中最著名的是 PHK 的 FreeBSD MD5 方案。

PHK方案的区别 和你将要使用的那个 你的社交购物车 2.0 应用很简单。你只是 将在盐和 a 上运行 MD5 密码并存储哈希。 PHK 运行 MD5 进行数千次迭代。 这就是所谓的“拉伸”。

【讨论】:

  • 总是在每个哈希循环中重新引入尽可能多的信息。我建议也将密码添加到内部 sha1 调用中。有关更多信息,请参阅this answer。另请参阅PBKDF2 Standard 进行按键拉伸
  • 不要使用sha1($hash . $salt),除非$salt 在每次哈希生成时都发生变化。如果不是这样,您正在增加发生碰撞的机会,原因与my answer 中所述的相同。
【解决方案3】:

简短的回答是否定的。当您链接两个哈希算法时,您所做的就是创建另一个具有未知属性的哈希算法(安全方面)。使用盐(甚至更好,HMAC)。

【讨论】:

    【解决方案4】:

    它必须通过哈希过程的次数越多,哈希所需的时间就越长,攻击者每天获得的尝试次数就越少。如果散列一次需要 10 毫秒,十次散列需要 100 毫秒,那么攻击者可以每分钟尝试 6000 个密码,散列一次,每分钟 600 个散列十次。当然,对于 Web 应用程序,试图以每分钟 6000 或 600 的速度进行暴力破解本质上是 DOS 攻击。为此目的,加密散列往往需要一段时间,而且多次散列也很常见。

    您可能应该使用 sha512 而不是 sha1,您可以使用 hash()hash('sha512',$stringtobehashed); 那样做,sha512 的哈希时间也比 sha1 长大约 5 倍。

    【讨论】:

    • 这是假设它运行在一个没有并行性的核心上。理论上它可以在许多内核上运行(12 核系统很常见,GPU 有更多)。更不用说使用流水线一次可以运行多个哈希,因此实际数字可能远高于每分钟 6k 个密码(如果一个体面的硬件不能达到每分钟 100k 或更多)...
    猜你喜欢
    • 1970-01-01
    • 2014-06-23
    • 2019-03-11
    • 2010-09-25
    • 2016-02-15
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多