文章作者:行者无疆 原文链接:http://www.cnblogs.com/rgbw/archive/2012/12/26/2834567.html
验证码的昨天、今天和明天
为什么要使用验证码
如果没有验证码,攻击者会使用有害程序自动注册大量的 Web 服务帐户,然后攻击者可以使用这些帐户为其他的用户制造麻烦,如发送垃圾邮件或通过同时反复登录多个帐户来延缓服务的速度。
然而,在大多数情况下,自动注册程序是不能很好的识别图片中的字符的。因此,为了防止攻击者编写程序来自动注册或者重复登录暴力破解密码,验证码技术应运而生。
当前,很多网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片, 图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。
什么是验证码
“验证码”的英文表示为CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart),翻译过来就是“全自动区分计算机和人类的图灵测试”,顾名思义,它是用来区分计算机和人类的。在 CAPTCHA 测试中,作为服务器的计算机会自动生成一个问题由用户来解答。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答 CAPTCHA 的问题,所以回答出问题的用户就可以被认为是人类。 CAPTCHA 是由计算机来考人类,而不是标准图灵测试中那样由人类来考计算机,因此人们有时称 CAPTCHA 是一种反向图灵测试。
现在每天有多达上亿的验证码被人类识别出来,因此CAPTCHA的需求量十分巨大,CAPTCHA需要能自动产生并且评估正确性。此外,人类必须要能够快速地识别并输入验证码,否则容易惹恼用户以至于用户流失。对于CAPTCHA,可以引入人工智能领域的难题,来使现有技术短期无法成功破解。如果一种CAPTCHA没有被破解,那么就有一个可以区分人类和计算机的方法。如果CAPTCHA被破解了,那么一个人工智能的问题也就随之解决了。
验证码的类型
文本验证码
文本验证码方便计算机自动地大量产生,是目前应用最多的最广泛的技术。文本验证码主要靠图像变形和添加噪声。
文本验证码破解难点主要在于字符的分割和识别。其中字符分割是破解文本验证码的关键。主要步骤是:第一步,分割字符,第二步,单个字符识别,其中单个字符的识别在现有的机器学习算法下可以很容易的识别。
所以防范对文本验证码的攻击的关键在于加大字符分割的难度。像Google等公司的验证码都是粘连在一起,分割难度大。
图像验证码
图像验证码基于图像分类、目标识别、场景理解等问题,一般情况下比文本验证码更加难以破解,但是现有的图像验证码需要庞大的图像数据库,而且无法大规模产生,更糟糕的是,一旦数据库被公布,算法不攻自破。
声音验证码
声音验证码以随机间隔播放随机选择的一个或多个人播报的数字字母,再添加背景噪声。声音验证码容易受到机器学习算法的攻击,而且相对于视觉上的验证码,用户友好性更低。对于字母的声音,可能农村地区的少部分群体会因为对于字母发音不熟悉而导致无法理解,而无法通过测试。
验证码的使用
服务器端随机生成验证码字符串,保存在内存中,并写入图片,发送给浏览器端显示,浏览器端输入验证码图片上字符,然后提交服务器端,提交的字符和服务器端保存的该字符比较是否一致,一致就继续,否则返回提示。攻击者编写的robot程序,很难识别验证码字符,顺利的完成自动注册,登录;而用户可以识别填写,所以这就实现了阻挡攻击的作用。而图片的字符识别,就是看图片上的干扰强度了。就实际的效果来说,验证码只是增加攻击者的难度,而不可能完全的防止。
验证码的困境
计算机程序可以一天24小时不间断运行,即使是在较低的识别率也可以在较短的时间内大量穿越CAPTCHA系统。所以CAPACHA的识别率需要低于0.01%才可以有效地阻挡自动化的恶意程序的攻击。
当然,也可以通过IP辅助来限制一台机器的尝试次数。
验证码的破解之道
道高一尺魔高一丈,只有了解验证码是怎么破解的,才能设计出更好的验证码。
破解主要流程
1 图像采集:直接通过HTTP抓起HTML,分析出图片的url,然后下载保存。
2 预处理: 检测是正确的图像格式,转换到合适的格式,压缩,剪切出ROI,去除噪音,灰度化,转换色彩空间等这些动作。
3 检测:主要是找出文字所在的主要区域。
4 前处理:做文字的切割。
5 训练:通过各种模式识别,机器学习算法,来挑选和训练合适数量的训练集。
6 识别:输入待识别的处理后的图片,转换成分类器需要的输入格式,然后通过输出的类和置信度,来判断大概可能是哪个字母。识别本质上就是分类。
对验证码设计的一些建议
1 在噪音等类型的使用上,尽力让字符和用来混淆的前景和背景不容易区分,尽力让坏人(噪音)长得和好人(字母)一样。
2 特别好的验证码的设计,要尽力发挥人类擅长而人工智能算法不擅长的。 比如粘连字符的分割和手写体(通过印刷体做特别的变形也可以),而不要一味的去加一些看起来比较复杂的噪音或者其他的花哨的东西,即使你做的足够复杂,但如果人也难识别,这样的验证码等于没有用。
3 从专业的机器视觉的角度说,验证码的设计,一定要让破解者在识别阶段,反复在低阶视觉和高阶视觉之间多反复几次才能识别出来,这样可以大大降低破解难度和破解的准确率。