解读验证码
-
验证码
为防止服务器端的资源被客户端的计算机程序滥用或攻击,服务器需要区分当前用户是计算机还是人类,一般在网站的关键操作位置都会采用验证码技术来区分。围绕验证码展开的攻防技术在Web安全中有着重要地位,本文将从验证码的工作原理出发,介绍验证码实现上容易产生的问题,并对其攻防技术现状和未来做一个简要介绍。
一、验证码是什么?
1.1 定义
验证码(CAPTCHA)是(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。
1.2 功能
- 防止恶意破解密码、刷票、论坛灌水
- 有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试
1.3 分类
- 传统静态图片
- 手机短信
- 邮件
- 语音
- 滑动
- 点击式的图文验证与行为辅助
二、实现流程
验证码的实现需要客户端、服务端的双方互动、通信,见下图所示。
- 客户端请求获取验证码。
- 服务端随机生成验证码,存储在内存或数据库中,并且设置一个超时时间。
- 服务端发送验证码到客户端。
- 客户端发送填写的验证码到服务端。
- 服务端先判断是否超时,再判断是否来自同一用户,最后判断是否相同。
三、技术细节
3.1 如何保存随机出来的验证码?
保存验证码是核心关键,没有保存就没有验证。为了使双端安全通信,服务端是不能将含有验证码的信息发送到客户端的,所以服务器需要在本地存储验证码,而非保存在传输报文中。
- 使用 redis 内存数据库十分快捷。
- 放入服务端的 session 也是不错的选择,也可以指定过期时间。session 只是存储一个验证码和过期时间的媒介,不应该把这个 session 传到客户端。
- 不推荐放在磁盘数据库中。因为验证码是具有时效性的,放在数据库中会影响一定的性能。
- 不能以 cookie 的形式保存在发送报文的报头中,否则在客户端会泄露验证码。
3.2 如何保持验证码的会话?
保持会话可以保证区分是不是原来的用户。通常 HTTP 请求无法保持连接,那么需要通过一种媒介(令牌)来保持通话记录。
- 对于手机、邮件来说,发送验证码时会发送指定的号码。这个号码就作为保持会话的媒介。在服务端可以根据这个号码生成随机数和 session。客户端再发送填写好的验证码时,当然会携带之前填写的指定号码,这样服务器就可以找到这个 session 了。
- 对于静态图片来说,发送的账号也可以作为保持会话的媒介。原理与手机、邮件的相同。
3.3 如何随机更加有效?
验证码的主要功能是区别人与机器。只要验证码在规定的时间、次数下能让机器不能正确地获取,那么验证码的使命就完成了。那对于验证码本身我们需要什么样子才是比较安全呢?
- 对于手机、邮件来说,通常是随机数字比较多,通常 4 - 6 位。如果长度太长,用户会不容易记住;如果太短,用户会觉得太简单。
- 对于静态图片来说,通常的做法是:将图片文字扭曲变形、加线、换颜色等等。
- 很多网站会使用字母与数字的结合,这样产生的随机数出现的概率会大大降低,但是不利用用户的填写输入。
3.4 如何设置超时时间?
验证码应该具有时效性,否则不法用户会不断尝试验证而通过,所以我们需要对验证码设定一个超时时间。因为网速、输入间隔等等因素的存在,验证码的时间间隔不可能十分的短。通常来说,手机短信的验证超时时间是 1 分钟,邮件 5 分钟,静态图片 1 分钟。
3.5 验证失败需要销毁验证码吗?
这个可以作为可选方案。如果每次失败需要重新获取验证码,这样又会花掉一定的等待时间,用户会产生一定的反感。当然我们可以设定失败 n 次后再销毁验证码。做这些事的初衷就是使得暴力破解的难度加大。
3.6 为什么需要规定验证码获取的次数,或者间隔时间?
为了防止不法用户通过这个接口来进行恶意短信攻击。如果没有设置限制次数或者是间隔时间,那么被攻击者就会不断地获取到该网站发送的验证码短信或邮件。这样一来服务器的效率会大大降低,公司会因为发送业务带来一定的额外费用,而用户接收到大量垃圾短信、邮件而对公司产生反感,甚至投诉这个公司,导致公司信誉降低。
四、验证码的缺陷
- 由于各个地区网络覆盖、管制的问题,验证码可能无法获取。
- 容易被木马伪造验证码信息。
- 产生了专门做手机验证码服务的卡商和刷单的赚客。
参考文章