← 返回博客列表

哈希与密码安全:不要在数据库里裸奔

在 Web 开发的早期,许多应用直接将用户的密码以纯文本(明文)的形式存储在数据库中。这意味着,一旦数据库遭遇拖库(数据泄露),黑客就能直接看到所有用户的密码。更糟糕的是,由于大多数人习惯在多个网站使用同一个密码,这会导致毁灭性的撞库攻击。

为了解决这个问题,开发者引入了**哈希(Hash)算法**。

哈希的魔法:不可逆性

哈希函数是一种特殊的数学算法,它能将任意长度的输入变成一段固定长度的乱码字符串(哈希值)。 它最大的特点是不可逆(单向性):你可以很容易地把 “password123” 变成一段哈希值,但绝对无法通过这段哈希值反算回 “password123”。

安全的登录流程变成了这样:

  1. 注册时:服务器计算用户密码的哈希值,并将哈希值存入数据库。
  2. 登录时:服务器计算用户输入密码的哈希值,并与数据库中存储的哈希值进行比对。如果一致,则密码正确。

这样一来,即使黑客拿到了数据库,看到的也只是一堆无法反解的哈希值。

MD5 与彩虹表攻击的覆灭

早年间,MD5 是最流行的哈希算法。但很快黑客们发现,虽然哈希不可逆,但我可以“暴力穷举”啊! 黑客们预先计算出几十亿个常用密码的 MD5 值,做成了一张巨大的对应表,这就叫彩虹表(Rainbow Table)。拿到数据库后,只要查表一对比,瞬间就能破解出大量弱密码。

救世主:“加盐(Salt)”

为了对抗彩虹表,安全专家们发明了“加盐”技术。 “盐”就是一段随机生成的长字符串。在计算哈希之前,系统会先把这把“盐”撒在密码上(拼接在一起),然后再计算哈希。

哪怕两个用户用了完全相同的密码 “123456”,因为系统为他们分配了不同的“盐”,最终存入数据库的哈希值也截然不同。这直接废掉了黑客预先计算好的彩虹表。

现代密码学最佳实践

如今,像 MD5 和 SHA-1 这样的算法因为计算速度太快,极易受到暴力破解攻击,已经被严禁用于密码存储。

现代开发者的标准做法是: 使用专门为密码设计的“慢速哈希算法”,如 bcrypt、Argon2 或 scrypt。 这些算法不仅自带随机加盐功能,还允许开发者配置“计算成本(Cost)”。计算成本越高,生成一个哈希值所需的时间就越长(可能需要几十毫秒)。对正常登录的用户来说,多等几十毫秒毫无感觉;但对于想每秒尝试几十万次密码的黑客来说,这简直是绝望的深渊。

保护用户数据,从放弃明文和 MD5 开始。