哈希
本文约需 2 分钟阅读
哈希 (Hash) 是将任意长度的数据转换为固定长度值的单向函数。它在密码保存中发挥着重要作用,用于以无法还原原始密码的形式安全地保管密码。相同的输入总会生成相同的哈希值,但从哈希值反推原始数据在计算上是困难的。
哈希与加密的区别
哈希和加密是容易混淆的概念,但二者有决定性的区别。加密是双向变换,使用正确的密钥即可将数据解密还原为原始数据。而哈希是无法还原为原始数据的单向变换,不存在解密这一概念。密码的保存适合使用哈希,因为服务方无需保留密码的明文,即使数据库泄露,原始密码也不会被直接暴露。相反,传输中的数据保护适合使用加密,因为如果接收者无法读取数据就失去了意义。
在密码保存中的应用
在安全的系统中,密码不会以明文形式保存,而是保存哈希化后的值。登录时会对输入的密码进行哈希化,并与保存的哈希值进行比较。代表性的哈希算法有 SHA-256 、 bcrypt 和 Argon2 。 SHA-256 速度很快,但对于密码用途而言太快了,因此推荐使用刻意提高计算成本的 bcrypt 或 Argon2 。截至 2025 年, OWASP 将 Argon2id 定位为最推荐的密码哈希算法。计算成本越高,对暴力破解攻击的抵抗力就越强。
为什么无法一次性完成旧哈希的迁移
当一个在密码保存上使用老旧算法的系统要迁移到新方式时,哈希的单向性本身就成了制约。由于保存的只有哈希值、无法还原为原始密码,数据库中的值无法一次性批量转换为新算法的哈希。服务方能够接触到明文密码的时刻,只有用户登录并输入密码的那一瞬间。因此实务中的迁移是渐进式的:在登录时用旧方式验证通过后,当场用新算法对明文重新哈希并替换保存值。不登录的用户的数据会继续保留旧哈希,所以在迁移期间需要能够判别新旧格式并分别验证的机制。不以明文保存密码这一设计上的优点,在迁移时反过来变成了额外的工作量,这是一个很好的例子。
哈希处理流程
实务中的陷阱与对策
仅靠简单的哈希化容易受到彩虹表攻击。作为对策,标准做法是在哈希化之前添加盐值 (随机数据) 。实务中常见的错误是使用 MD5 或 SHA-1 等老旧算法对密码进行哈希化。这些算法速度过快,使用 GPU 的攻击能在短时间内计算出大量哈希值。又长又随机的密码,即使在哈希化的状态下,也对暴力破解攻击具有很高的抵抗力。
这篇文章对您有帮助吗?