用户名和口令
首先,咱们先来讲说用户名和口令的事。这并非本站第一次谈论这个事了。如何管理本身的口令让你知道怎么管理本身的口令,破解你的口令让你知道在现代这样速度的计算速度下,用穷举法破解你的口令可能会是一件很轻松的事。在这里我想告诉从开发者的角度上来作设计这个用户名和口令的事。下面一几件规则:html
- 限制用户输入一些很是容易被破解的口令。如什么qwert,123456, password之类,就像twitter限制用户的口令同样作一个口令的黑名单。另外,你能够限制用户口令的长度,是否有大小写,是否有数字,你能够用你的程序作一下校验。固然,这可能会让用户感到很不爽,因此,如今不少网站都提供了UX让用户知道他的口令强度是什么样的(好比这个有趣的UX),这样可让用户有一个选择,目的就是告诉用户——要想安全,先把口令设得好一点。
- 千万不要明文保存用户的口令。正如如何管理本身的口令所说的同样,不少时候,用户都会用相同的ID相同的口令来登陆不少网站。因此,若是你的网站明文保存的话,那么,若是你的数据被你的不良员工流传出去那对用户是灾难性的。因此,用户的口令必定要加密保存,最好是用不可逆的加密,如MD5或是SHA1之类的有hash算法的不可逆的加密算法。CSDN曾明文保存过用户的口令。(另,对于国内公司的品行以及有关部门的管理方式,我不敢保证国内网站以加密的方式保存你的口令。我以为,作为一个有良知的人,咱们应该加密保存用户的口令)
- 是否让浏览器保存口令。咱们有N多的方法能够不让浏览器保存用户名和口令。可是这可能对用户来讲很不爽。由于在真实世界里谁也记得不住那么多的口令。不少用户可能会使用一些密码管理工具来保存密码,浏览器只是其中一种。是否让浏览器保存这个须要你作决定,重点是看一下你的系统的安全级别是否要求比较高,若是是的话,则不要让浏览器保存密码,并在网站明显的位置告诉用户——保存口令最安全的地方只有你的大脑。
- 口令在网上的传输。由于HTTP是明文协议,因此,用户名和口令在网上也是明文发送的,这个很不安全。你能够看看这篇文章你就明白了。要作到加密传输就必需使用HTTPS协议。可是,在中国仍是有不少网站的Web登陆方式还在使用ActiveX控件,这可能成为IE6还大量存在的缘由。我一般理解为这些ActiveX控件是为了反键盘记录程序的。 不过,我依然觉ActiveX控件不该该存在,由于在国外的众多安全很重要的站点上都看不到ActiveX的控件的身影。
用户登陆状态
首先,我想告诉你们的是,由于HTTP是无状态的协议,也就是说,这个协议是没法记录用户访问状态的,其每次请求都是独立的无关联的,一笔是一笔。而咱们的网站都是设计成多个页面的,所在页面跳转过程当中咱们须要知道用户的状态,尤为是用户登陆的状态,这样咱们在页面跳转后咱们才知道是否可让用户有权限来操做一些功能或是查看一些数据。java
因此,咱们每一个页面都须要对用户的身份进行认证。固然,咱们不可能让用户在每一个页面上输入用户名和口令,这会让用户以为咱们的网站至关的SB。为了实现这一功能,用得最多的技术就是浏览器的cookie,咱们会把用户登陆的信息存放在客户端的cookie里,这样,咱们每一个页面都从这个cookie里得到用户是否登陆的信息,从而达到记录状态,验证用户的目的。可是,你真的会用cookie吗?下面是使用cookie的一些原则。程序员
- 千万不要在cookie中存放用户的密码。加密的密码都不行。由于这个密码能够被人获取并尝试离线穷举。因此,你必定不能把用户的密码保存在cookie中。我看到太多的站点这么干了。
- 正确设计“记住密码”。这个功能简直就是一个安全隐患,我以为并非全部的程序员都知道怎么设计这个事。通常的设计 是——一时用户勾选了这个功能,系统会生成一个cookie,cookie包括用户名和一个固定的散列值,这个固定的散列值一直使用。这样,你就能够在全部的设备和客户上均可以登陆,并且能够有多个用户同时登陆。这个并非很安全。下面是一些更为安全的方法供你参考:
(——更新 2011/08/26,原文中有些小错误,而且说的不清楚,从新调整了一下——)
1)在cookie中,保存三个东西——用户名,登陆序列,登陆token。算法
用户名:明文存放。
登陆序列:一个被MD5散列过的随机数,仅当强制用户输入口令时更新(如:用户修改了口令)。
登陆token:一个被MD5散列过的随机数,仅一个登陆session内有效,新的登陆session会更新它。shell
2)上述三个东西会存在服务器上,服务器的验证用户须要验证客户端cookie里的这三个事。数据库
3)这样的设计会有什么样的效果,会有下面的效果,浏览器
a)登陆token是单实例登陆。意思就是一个用户只能有一个登陆实例。安全
b)登陆序列是用来作盗用行为检测的。若是用户的cookie被盗后,盗用者使用这个cookie访问网站时,咱们的系统是觉得是合法用户,而后更新“登陆token”,而真正的用户回来访问时,系统发现只有“用户名”和“登陆序列”相同,可是“登陆token” 不对,这样的话,系统就知道,这个用户可能出现了被盗用的状况,因而,系统能够清除并更改登陆序列 和 登陆token,这样就能够令全部的cookie失效,并要求用户输入口令。并给警告用户系统安全。服务器
4)固然,上述这样的设计仍是会有一些问题,好比:同一用户的不一样设备登陆,甚至在同一个设备上使用不一样的浏览器保登陆。一个设备会让另外一个设备的登陆token和登陆序列失效,从而让其它设备和浏览器须要从新登陆,并会形成cookie被盗用的假象。因此,你在服务器服还须要考虑- IP 地址,cookie
a) 若是以口令方式登陆,咱们无需更新服务器的“登陆序列”和 “登陆token”(但须要更新cookie)。由于咱们认为口令只有真正的用户知道。
b) 若是 IP相同 ,那么,咱们无需更新服务器的“登陆序列”和 “登陆token”(但须要更新cookie)。由于咱们认为是同一用户有同一IP(固然,同一个局域网里也有同一IP,但咱们认为这个局域网是用户能够控制的。网吧内并不推荐使用这一功能)。
c) 若是 (IP不一样 && 没有用口令登陆),那么,“登陆token” 就会在多个IP间发生变化(登陆token在两个或多个ip间被来来回回的变换),当在必定时间内达到必定次数后,系统才会真正以为被盗用的可能性很高,此时系统在后台清除“登陆序列”和“登陆token“,让Cookie失效,强制用户输入口令(或是要求用户更改口令),以保证多台设备上的cookie一致。
- 不要让cookie有权限访问全部的操做。不然就是XSS攻击,这个功能请参看新浪微博的XSS攻击。下面的这些功能必定要用户输入口令:
1)修改口令。
2)修改电子邮件。(电子邮件一般用来找回用户密码,最好通发邮件或是发手机短信的方式修改,或者干脆就不让改一一用电子邮件作账号名)
3)用户的隐私信息。
4)用户消费功能。
- 权衡Cookie的过时时间。若是是永不过时,会有很不错的用户体验,可是这也会让用户很快就忘了登陆密码。若是设置上过时期限,好比2周,一个月,那么可能会好一点,可是2周和一个月后,用户依然会忘了密码。尤为是用户在一些公共电脑上,若是保存了永久cookie的话,等于泄露了账号。因此,对于cookie的过时时间咱们还须要权衡。
找回口令的功能
找回口令的功能必定要提供。可是不少朋友并不知道怎么来设计这个功能。咱们有不少找回口令的设计,下面我逐个点评一下。
- 千万不要使用安全问答。事实证实,这个环节很烦人,并且用户并不能很好的设置安全问答。什么,个人生日啊,我母亲的生日,等等。由于今天的互联网和之前不同了,由于SNS,今天的互联比之前更真实了,我能够上facebook,开心,人人网,LinkedIn查到你的不少的真实的信息。经过这些信息我可使用安全问答来重设你的口令。 这里须要说一下 Facebook,Facebook的安全问答很强大,还要你经过照片认人,呵呵。
- 不要重置用户的密码。由于这有可能让用户的密码遭到恶意攻击。固然,你要发个邮件给用户让其确认,用户点击邮件中的一个连接,你再重置。我并不推荐这样的方法,由于用户通常都会用笔记下来这个很难记的口令,而后登陆系统,由于登陆系统时使用了“记住密码”的功能,因此致使用户不会去修改密码,从而要么导到被写下来的密码被人盗取,要么又忘记了密码。
- 好一点的作法——经过邮件自行重置。当用户申请找回口令功能的时候,系统生成一个MD5惟一的随机字串(可经过UID+IP+timestamp+随机数),放在数据库中,而后设置上时限(好比1小时内),给用户发一个邮件,这个链接中包含那个MD5的字串的连接,用户经过点击那个连接来本身从新设置新的口令。
- 更好一点的作法——多重认证。好比:经过手机+邮件的方式让用户输入验证码。手机+邮件可能还不把握,由于手机要能会丢了,而个人手机能够访问个人邮箱。因此,使用U盾,SecureID(一个会变化的6位数token),或是经过人工的方式核实用户身份。固然,这主要看你的系统的安全级别了。
口令探测防守
- 使用验证码。验证码是后台随机产生的一个短暂的验证码,这个验证码通常是一个计算机很难识别的图片。这样就能够防止以程序的方式来尝试用户的口令。事实证实,这是最简单也最有效的方式。固然,老是让用户输入那些肉眼都看不清的验证码的用户体验很差,因此,能够折中一下。好比Google,当他发现一个IP地址发出大量的搜索后,其会要求你输入验证码。当他发现同一个IP注册了3个以上的gmail邮箱后,他须要给你发短信方式或是电话方式的验证码。
- 用户口令失败次数。调置口令失败的上限,若是失败过多,则把账号锁了,须要用户以找回口令的方式来从新激活账号。可是,这个功能可能会被恶意人使用。最好的方法是,增长其尝试的时间成本(之前的这篇文章说过一个增长时间成本的解密算法)。如,两次口令尝试的间隔是5秒钟。三次以上错误,账号被临时锁上30秒,5次以上账号被锁1分钟,10次以上错误账号被锁4小时……可是这会致使恶意用户用脚原本攻击,因此最好再加上验证码,验证码出错次数过多不由止登陆而是禁lP。
- 系统全局防守。上述的防守只针对某一个别用户。恶意者们深知这一点,因此,他们通常会动用“僵尸网络”轮着尝试一堆用户的口令,因此上述的那种方法可能还不够好。咱们须要在系统全局域上监控全部的口令失败的次数。固然,这个须要咱们平时没有受到攻击时的数据作为支持。好比你的系统,平均天天有5000次的口令错误的事件,那么你能够认为,当口令错误大幅超过这个数后,并且时间相对集中,就说明有黑客攻击。这个时候你怎么办?通常最多见使用的方法是让全部的用户输错口令后再次尝试的时间成本增长。
最后,再说一下,关于用户登陆,使用第三方的 OAuth 和 OpenID 也不失为一个很不错的选择。