[英]openssl_digest vs hash vs hash_hmac? Difference between SALT & HMAC?
我想使用SHA512来存储密码。 要做到这openssl_digest
,我应该使用openssl_digest
, hash
和hash_hmac
哪一个?为什么?
SALT
和HMAC
什么区别?
我刚刚读到HMAC是建立在哈希函数之上的。
SHA512+SALT+HMAC
真的有必要还是SHA512+SALT
或SHA512+HMAC
?
所以,首先,让我们清楚一件事。 openssl_digest()
=== hash()
。 它只是另一个不同名称的功能,完全相同。 它计算输入的加密哈希值。
所以,现在我们有了一个问题: 存储密码时哪个更好: hash
或hash_hmac
?
也不
事实证明, 彩虹表已经死了 。 只使用hash($password . $salt)
甚至hash_hmac($password, $salt)
对于密码存储来说还不够好。 期。 如果您这样做,请立即停止。
原因很简单:计算机(或GPU)上的计算时间非常便宜。 这是如此便宜,以至于蛮力的密码列表足够便宜,你需要担心它。 请记住,哈希函数设计得很快 。 不贵啊...
但是,事实证明,有一种方法可以使这些快速哈希函数更加昂贵。 事实上,它非常简单:迭代。
现在,我知道你在想什么。 你将只是循环哈希:
function hash_password($password, $salt) {
$hash = hash("sha512", $password . $salt);
for ($i = 0; $i < 1000; $i++) {
$hash = hash("sha512", $hash);
}
}
当然这很好,对吧? 不。 正如Hashing和Encryption之间的基本差异所解释的那样,这不是一个好主意。 那么为什么不再重新输入密码和盐呢?
function hash_password($password, $salt) {
$hash = hash("md5", $salt . $password);
for ($i = 0; $i < 1000; $i++) {
$hash = hash("md5", $hash . $password);
}
}
事实上,这正是PHPASS使用的(略微调整,但这是基本算法)...
所以现在1调用hash_password
执行1000个哈希循环。
但我们可以改进吗?
好吧,事实证明,我们可以。 下一个合乎逻辑的做法是看看我们是否可以在相同的时间内获得更多的哈希循环。 这就是hash_hmac()
用武之地。事实证明, HMAC
每次调用时都会使用2个哈希周期。 而且因为它都是C,所以它只需要hash()
执行一轮的时间量的1.5倍。
这意味着如果我们用hash_hmac
替换hash
,我们可以立即看到在指定时间内完成的工作量增加了33%。 所以现在我们在这里:
function hash_password($password, $salt) {
$hash = hash_hmac("md5", $salt, $password);
for ($i = 0; $i < 1000; $i++) {
$hash = hash_hmac("md5", $hash, $password);
}
}
这实际上是PBKDF2的基本内循环。
但我们可以变得更好吗?
是的,再次,我们可以变得更好。 如果我们仔细观察,我们可以看到 - 除了密码和盐 - 所有上述算法都使用非常少量的内存。 在sha512的情况下,它们将使用128到256字节(缓冲区和状态)的顺序来散列密码。 由于内存使用量非常小,因此在GPU中并排运行大量内存非常简单。 如果我们只能增加内存使用量......
好吧,事实证明,我们可以简单地使用bcrypt
,这是一种自适应散列算法。 它的优点是它使用比上述算法更多的内存(大约4到5kb)。 因此,对并行化更具抵抗力。 并且由于它的计算成本很高,因此它对强制执行是不利的。
幸运的是,它适用于PHP:
crypt($password, '$2y$07$usesomesillystringforsalt$')
请注意, crypt()
使用许多算法,但$2y$
和$2a$
算法是bcrypt
。
但我们能改进吗?
的种类。 有一种叫做scrypt的相对较新的算法。 它比bcrypt更好,因为它的计算成本非常高,但是使用了更多的内存(大约20mb到40mb来散列单个密码)。 因此,对并行化更具抵抗力......
不幸的是,PHP中还没有 scrypt
(我正在努力改变它)。 在那之前,使用bcrypt
......
在LinkedIn , LastFM , Hotmail , Gawker等最近的经验教训之后,很明显很多人都做错了。 不要做错,使用带有审查算法的库。 使用CRYPT_BLOWFISH
(bcrypt),使用PHPASS,使用PasswordLib 。 但是不要仅仅因为你不想依赖而发明自己的......这只是疏忽。
更多阅读:
HMAC是使用哈希算法(如SHA512)的特定方法。 它用于签署消息,然后您可以验证消息是否来自特定签名者并且未被更改。 所以这不是你想要的。
salt用于向应加密或散列的文本添加一些“随机性”。 关键是,即使您多次加密相同的文本,您也会得到不同的结果。 这使得进行一些攻击变得更加困难。 这就是你想要的: SHA512(salt+password)
。
对于存储密码,我能想象的最安全的方式是:
(免责声明:我对加密技术不是很熟悉,可能有更好的解决方案)
要验证密码,您需要执行以下操作:
当然,你可以用明文传输密码并在服务器上进行整个salting和散列,但这会大大削弱你的解决方案。 您绝不应以明文形式传输密码。
但是“将盐传递给客户”部分可能是个问题。 我可以想象解决这个问题的一种方法是以某种方式从用户名中获取salt(最简单的方法:只做lowercase(username) + password
),但问题是盐可以预测,从而削弱你的解决方案一点点。 然而,它仍然方式比发射“原始”哈希更好,你甚至不会需要存储的盐,你可以从用户名,每次得到它。 如果您的密码数据库被盗,它仍然可以通过这种“用户名腌制”方法抵御彩虹表攻击。
问题是仍然可能发生中间人攻击。 如果攻击者拦截用户名和哈希,则它具有所有相关的信息,并且与发送明文密码没有任何不同。 因此,您可能希望使用SSL(HTTPS)保护连接。
根据IT安全专家的说法:
使用Bcrypt来源: https : //security.stackexchange.com/a/10905/7599 。
我会根据SO的观点给出答案。
openssl_digest vs hash vs hash_hmac
并且在密码学中, 基于散列的消息认证码(HMAC)是用于计算涉及密码散列函数结合密钥的消息认证码(MAC)的特定结构。
正如ircmaxell所说, hash
或hash_hmac
对于使用SHA-512存储密码并不是更好。 我宁愿说,您可以使用openssl_digest
存储密码。
SALT vs HMAC
HMAC旨在用于您拥有随机密钥的情况。 对于这些情况,HMAC通常比将密钥合并到散列函数中的其他方式更好。 (例如,使用HMAC处理扩展攻击等事情)
盐通常是一个非秘密的随机值。 也就是说,当你使用术语salt时,通常指的是攻击者可能已经知道随机值的情况。 因此,系统的安全性不应取决于保密的盐。 在这些情况下,HMAC通常不是一个很好的选择。
HMAC和Salt比较不合逻辑。 就个人而言,我会使用一个salt和一个哈希函数......我不会对哈希函数的强弱感到偏执,因为它不太可能成为任何实际系统中的薄弱环节....
请参阅http://www.derkeiler.com/Newsgroups/sci.crypt/2006-01/msg00321.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.