虽然我不是这个领域的专家,但我仍在不断地努力了解哪些方法被认为是安全的,用于存储密码和加密数据。
在我的研究中,我拼命地试图提取对实践很重要的关键点:-)我经常读到某些哈希函数适合于密码哈希,但不适合导出加密密钥,反之亦然。因为我完全搞不懂这个,但读得太多了,所以我不得不寻求帮助。
对于下面的内容,让我们忘记所有复杂的事情(彩虹表、盐渍、侧通道攻击等等)。此外,我在下面的章节中过分简化了一些事情。但是这个问题是如此的基本,所以我认为在这种情况下,过于简单化并没有坏处。
我的理解问题是:
由于明显的原因,操作系统不应该以明文形式保存密码。所以一个散列函数(MD4 (是的,Windows仍然使用它),SHA-2,scrypt,.)应用于密码,并将散列存储在磁盘上而不是密码上。
如果攻击者想破解密码,他必须获得哈希,然后必须获取每个可能的输入字符串,对其应用散列函数,并查看输入字符串的哈希是否与操作系统存储的密码的哈希相同。
这意味着哈希函数应该是缓慢的(就周期而言),应该很难并行化,并且应该是内存密集型的,以使蛮力破解(即使是使用专门的硬件)尽可能地昂贵和耗时。
另一方面,据我所理解,当从密码导出加密密钥时,应用的方法几乎相同。不同之处在于,密码的散列不是存储在磁盘上,而是直接用作某些对称加密方法(如AES)的加密密钥(过于简化,但显示了一般的思想,对吗?)
现在,如果攻击者想破解加密,他还必须测试每个可能的密码,将哈希函数应用到密码中,然后使用哈希解密加密数据,并测试结果是否包含有意义的内容。因此,与密码哈希一样,哈希函数应该很难并行化、内存和循环密集,这样攻击者每秒只能测试几个加密密钥(= hashes)。
因此,哈希函数对哈希密码的要求似乎与哈希函数的要求相同,哈希函数的输出被用作加密密钥。对于我来说,我不明白为什么某些散列函数被认为适合其中一个,而不是另一个,反之亦然。
请有人用简单的话来解释这一点,考虑到我一般都有数学背景(如果急需的话:-),但没有密码学的数学背景?
发布于 2018-01-26 18:12:08
因此,哈希函数对哈希密码的要求似乎与哈希函数的要求相同,哈希函数的输出被用作加密密钥。
只有从密码派生出加密密钥时,这才是正确的。
您所观察到的相似之处在于,密码是输入,密码往往比较容易猜测。
导出加密密钥的其他情况不需要扩展密钥,因为输入已经是不可猜测的(Psuedo)随机值。
例如,在使用密钥协商方案时,所得到的共享秘密通常使用快速密码散列函数(如SHA256 )进行散列,以在共享密钥被泄露的情况下保护私钥。由于该值已经是随机的,并且足够大,无法猜测,因此没有必要应用缓慢的散列来阻止对手猜测它的能力。
博士
如果输入是密码,则哈希需要慢一点,以防止对手对整个密码空间执行彻底搜索的能力。
如果哈希的输入已经是一个较大的随机值,则不需要慢散列。
发布于 2018-01-26 18:35:23
实际上,为加密密钥的派生而设计的哈希函数通常不适合直接散列密码;反之亦然。
例如,像SHA-256这样的标准哈希函数可以很好地在某些情况下导出加密密钥,例如从Diffie-Hellman密钥交换建立的更大但不完美的共享秘密。HMAC-SHA-256非常适合于从任何大型主密钥和密钥索引中导出多个加密密钥。但是,SHA-256和HMAC-SHA-256都不能直接用于散列密码,原因是:它们太快了。顺便说一下,SHA-256没有明确的盐分输入,因此需要修改。
另一方面:键派生函数应该产生接近均匀分布的位串的结果。对密码哈希函数不存在这种要求(或者只是温和地,这样就不会大幅度地扩大密码文件)。因此,有些密码的输出中有意有一个低熵部分(如版本、迭代计数或salt副本),或者/并将其输出格式化为ASCII文本。独立地,它们的输入可以在某种程度上受到限制(bcrypt就是这种情况:大多数实现都有有限的输入长度,或者默默地截断大输入;在处理之前,有些方法会对密码输入进行清理)。很多密码哈希都认为密码输入中的零字节标志着它的结束,这对于一般使用密钥派生函数来说是非常糟糕的。
另一方面,一个好的密码散列函数可以通过一个参数降低到可以忽略不计的程度,该函数将所有输入作为任意位处理,并且具有接近均匀分布的输出(如PBKDF2),应该可用于密钥派生。
https://crypto.stackexchange.com/questions/55045
复制相似问题