本文为你讲解如何安全的存储密码,使用 bcrypt 加密存储,即使你的数据库被泄露也不会怕泄露密码。

密码存储常见方法

  1. 明文存储
    如果对安全性要求不高,可能很多人会直接选择明文存储,但是泄露数据库则泄露密码,极其不安全。
  1. MD5/SHA256 进行哈希
    对密码进行 MD5/SHA256 哈希计算,然后把结果存入数据库,这样就算你数据库被泄露,也不会直接泄露密码,但是现在有一些在线工具存储了大量的哈希值,可以反向查询破解;另外还有更高端的彩虹表破解。

  2. MD5/SHA256 + 盐:
    为了防止反向字典查询破解和彩虹表破解,就衍生出了加盐的做法,也就是在原有字符串后面增加一些其他的字符,使得哈希值跟原始的不一样,因为别人不知道你加了什么“料”在里面,也就无法字典反向破解了,但是要确保你的盐不要泄露。

随机盐

为了更加的安全,我们不应该所有密码都共用一个盐salt,应该每次存储密码都使用不同的盐。
你可以生成一个随机的盐salt,然后把密码和盐都保存到数据库,下次计算时还需要读取到这个加密时用的盐来进行判断是否相符。
如果你使用相同的盐,存在多个人使用同个密码时,破解其中一个,其他也都破解了。

使用更安全的 Bcrypt 加密存储

Bcrypt 就是一个非常方便的工具,它可以为你生成随机的盐,结合你的密码进行一大串非常复杂的计算,最后生成一个字符串,只需要保存这一个字符串,不需要单独另外存储一个salt字段,它还提供了一个判断是否相符的方法,使用起来相当方便。
由于 bcrypt 的计算比较复杂,所以反向破解需要非常多的时间,但是也会增加你CPU的负担,哈希一次密码可能需要一小段时间。在线试下 bcrypt

下面是密码 123456 使用 bcrypt 进行随机加盐后哈希出来的一个字符串,我们就是存储这串到数据库就行了,泄露这一串别人根本无法知道原始密码。
字符串以 $ 做分隔符,其中包含了几个信息,第一部分的 2b 表示算法版本,第2部分的 10 表示进行多少轮计算;第 3 部分的前 22 个字符是盐,后面的是哈希值。
$2b$10$N9D5ZPZS7zNC5dDoMekfwuQucqPKJ1A6iztd7ARFaxEbHH.FRAWdK

bcrypt 有不同语言的实现,根据你的需要看看吧:
Python 版本
NodeJS 版本
Go 版本
PHP 有方法支持,只需要传递一个参数

另外除了 bcrypt 还有 Argon2 密码哈希算法,nodejs 可以看看 这个在线试下