web 应用最常见的认证方式就是通过用户名与密码进行认证。
1 区分认证与授权
首先我们要区分清楚认证与授权。认证(Authentication) 是为了认出用户的身份;而授权(Authorization )则是为了决定该身份的用户能够做什么 。
认证实际上是一个验证凭证的过程 。 如果只有一个凭证被用于认证 , 则称为 “ 单因素认证 ”; 如果有两个及以上的凭证被用于认证 , 则称为 “ 多因素认证 ”。 多因素认证的安全性会高于单因素认证 , 但会影响用户体验。
2 密码
密码认证的优点是:使用成本低 , 因为认证过程实现起来很简单 ; 缺点是:密码可能会被猜解 。
2.1 密码强度
这里引用 OWASP 推荐的一些最佳实践并结合实际应用,从以下几个维度来说明密码强度:
(1) 密码长度
- 普通应用,密码长度为 6 位以上;
- 重要应用,密码长度为 8 位以上 , 并考虑使用多因素认证 。
(2) 密码复杂度
- 密码区分大小写字母;
- 密码为大写字母 、小写字母 、数字以及特殊符号中,两种以上的组合;
- 不能是连续性的字符 , 比如 1234abcd,因为这种顺着人的思维方式,很容易被猜解;
- 尽量避免出现重复的字符 , 比如 33331。
(3) 密码来源
不要使用我们的公开数据 , 或者是与个人隐私相关的数据作为密码 。 比如微信号、 QQ 号 、 身份证号码 、 昵称 、 电话号码、手机号码 、 生日 、 英文名 、 公司名等作为密码 , 因为这些资料往往可以从互联网上获得,所以不安全。
2.2 弱密码库清单
互联网上有许多弱密码库清单可供下载。我们可以找一份比较全的弱密码库清单。如果用户使用的密码包含在这份列表中 , 就提示该用户密码不安全,并弹出密码修改链接。
弱密码之所以可怕,是因为黑客会选择一些弱密码进行暴力破解 , 比如使用经典的弱密码 “123456”,然后不断猜解用户名 , 直到发现一个使用该弱弱密码的账户为止 。由于用户名往往是公开的信息 ,所以黑客会收集一份用户名清单 , 利用这份清单进行暴力破解,这种攻击成本非常低 , 但效果却比暴力破解密码要好很多。
2.3 密码保存方式
一般来说 , 密码必须以不可逆的加密算法 , 或单向散列函数算法 , 加密后存储在数据库中 。 这样做的目的是:尽最大可能来保障密码的安全。因为即便是 DBA , 也不能够知道用户的明文密码。所以即使黑客入侵了网站数据库 , 也无法获取用户的实际密码。
2011 年 12 月 , 国内最大的开发者社区 CSDN 的数据库被黑客公布在网上 。 因为 CSDN 将用户的密码明文保存在数据库中 , 从而导致 600 万 的 CSDN 用户密码发生泄露!
目前业界比较普遍的做法是:在用户注册时将明文密码经过哈希后 ( 比如 MD5 或者 SHA-1) 再保存到数据库中;用户登录时,只需要验证用户提交的 “ 密码字符串 ” 哈希值 , 与保存在数据库中的 “ 密码密文 ” 哈希值是否一致即可。
因为 MD5 最流行,所以黑客使用一种叫做 “ 彩虹表 ( Rainbow Table)” 的破解 MD5 密码的方法。该方法会尽可能多地收集密码的明文与明文对应的 MD5 值 。程序还可以周期性地计算一些数据的 MD5 值 , 以扩充彩虹表的内容 。这样只需要查询 MD5 值 , 就能找到该 MDS 值对应的明文! 一个好的彩虹表 , 会非常庞大,甚至达到万亿条记录!
网上也有很多在线工具,可以提供 MD5 破解服务:
为了避免密码密文(哈希值)发生泄露后 , 黑客能够通过彩虹表查询出密码明文的情况发生,我们在计算密码明文的哈希值时 , 可以增加一个 “Salt ”。“Salt"” 是一个随机生成的字符串 , 它的作用是为了增加明文的复杂度 , 这种方法会使黑客通过彩虹表攻击失效 。Salt 可以这样使用:
- MD5(Password+Salt )
- MD5(Username+Password+Salt )
- MD5(MD5(Username+Password+Salt ))
计算公式越复杂,生成的密文越安全。
Salt 一般保存在服务器端的配置文件中 , 注意:一定要妥善保管。