Web安全之密码安全
禁止存储明文密码
不要把用户原始密码直接保存到数据库。
例子,用户注册填写密码 123321
- 错误做法:数据库直接存明文
123321 - 正确做法:对密码做哈希加密,保存加密后的字符串,例如:
dsfdsfwrefdsfa32efsfdsfds
疑惑:加密之后登录时密码不就对不上了吗?
我们不需要解密拿到原始密码。
登录逻辑:用户输入的密码,使用和注册时完全相同的哈希算法再加密一次,拿登录加密后的结果,和数据库里存储的加密字符串做比对即可,两者相等代表密码正确。
流程:
- 注册:原始密码 → 哈希加密 → 存入数据库
- 登录:用户输入密码 → 相同哈希加密 → 和库中密文对比
MD5 的缺陷
早期经常使用 MD5 做密码哈希,单纯MD5并不安全。
网上有网站直接通过穷举法把大量的随机密码和对应的密码的MD5事先保存到数据库中,可以直接反向破解简单密码,容易被撞库。
加盐(Salt)处理
加盐:密码拼接一段随机字符串(盐值)之后,再执行加密,大幅提升破解难度。
示例:
MD5(用户密码 + 盐值)
MD5(pwd + "stat")Code language: JavaScript (javascript)
要点
- 盐值不要写死固定字符串,最好每个用户使用独立随机盐;
- 盐值也需要存储在数据库,登录时取出同一个盐,和用户输入密码再一起哈希;
- 生产环境优先使用 BCrypt、PBKDF2、Argon2,比MD5加盐更加适合密码存储。
业务流程
- 用户注册:拿到密码,生成随机盐 →
哈希(密码+盐)→ 密文+盐一起入库 - 用户登录:拿到输入密码,读取该用户数据库的盐 →
哈希(输入密码+盐),和数据库密文对比,相等即校验通过。
Previous: SQL注入攻击
Next: Cookie的安全问题