科学网

 找回密码
  注册

tag 标签: 验证码

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

验证码——你要浪费我们多少时间?
热度 2 eriklee1895 2012-5-20 22:24
不知道你是否为登陆 XX 网站输入用户名、密码的同时还要输入难以辨认的验证码而恼火? 在现代社会,但凡出了点什么问题,首先想到的是靠设置障碍来解决。不幸的是,这些屏障往往只会给守规矩的好公民添麻烦,对捣乱的坏家伙反而没啥用。黑客总是有办法绕开这些屏障。 现如今,要输入验证码才能进入的网站比比皆是。验证码的英文是 CAPTCHA ,是 Completely Automated Public Turing Test To Tell Computers and Humans Apart 的首字母缩写,中文意思就是“全自动区分计算机和人类的图灵测试”。这个东西就是一串在你网上注册时经常出现的的歪七扭八的字符——既有确实存在的英文单词,也有无实际意义的字幕组合。你需要用键盘把你看到的字符录入到一个文本框中。 验证码这个东西是由 卡内基梅隆大学 的研发人员设计的,其目的是用来防范那些可能对在线服务造成威胁的僵尸程序(一种自动执行的黑客或木马程序)。比如说有些僵尸程序会注册大量的邮箱账号,然后肆意传播垃圾邮件;有的会发布一些虚假信息,企图以此提升网站的搜索排名。 研究人员设计验证码这个东西是基于这样一个理论:只有真人才能识别出验证码图片中的字符。歪歪扭扭的字符连同杂乱的背景,人眼可以看清,计算机则不行。这样的话,一切看起来都很完美:放行好人,拦截坏人。 看起来是一道完美的屏障,是吧?但是,实际上,验证码不过是以暴制暴的粗糙手段。首先,验证码中的图片常常歪歪扭扭的连人眼都认不出来,或者是很容易混淆。我想,大家一定都有这样的经历吧?比如说,“ rl10Ozirl ”这串验证码, l 和 1,0 和 O ,在歪歪扭扭的情况下有多少人可以不假思索地区分出来?而我就更搞笑了,有时候我都不确定验证码图片中到底有几个字符,因为有的长得像数字 1 或 0 的图案其实是背景干扰 -_-! 。这样,无形中,每天我们为了识别讨厌的验证码,耗费了我们大量时间,虽然大多数人都未曾察觉,而仅仅是在内心中小小的抱怨一下。 而更严重的问题是,验证码这种方式其实把很多人群挡在了外面,比如说盲人,他们就无法玩儿这样的图片验证游戏。 于是乎,出现了验证码的改进版本(如果这不算是打自己的脸的话 ~~~^_^~~~ )。例如,添加一个按钮,能够让你在看不清当前图片时另换一张,还有为盲人设计的语音验证码。不过,最重要的是,在这场技术大战中,验证码败象简陋。正所谓道高一尺魔高一丈,捣乱分子总有办法绕开验证码这一障碍。 当然,也有网站开始尝试弃用这种糟糕的验证码,改为用户体验稍好的方式,比如做道简单的数学题,回答一个简单的问题等等。即便是这样,还是是免不了将某些特殊群体挡在外面——显然这不是设计者的初衷。 根据卡内基梅隆大学的研究小组估算,全球人口每天在这些烦人的屏障入口处所耗费的时间,累计可达 150,000 小时。对于我们这些守规矩的用户,这简直就是对生命的可耻浪费!一定还有其他更好的解决方案。 或许应该设计一款自愿出示的互联网通用身份证,或者视网膜扫描之类的。总之,那些浪费我们时间的防御机制真的该改变一下了! (注:本文素材来自于《环球科学杂志》 2012.4 月刊《取缔验证码正当时》一文)
个人分类: 生活杂谈|4456 次阅读|1 个评论
验证码也可以赚钱
热度 3 lhj701 2012-5-12 12:09
验证码也可以赚钱 网上经常遇到需要填写验证码,过去都是英文,现在逐渐出现中文 的 验证码,出现的几个字还没有意义,不太好写和记忆。 如果利用这个验证码,做下广告,比如某些商品的名称(英文也 行)或广告词,但不要太长,就三四个字以内,打字时,许多拼音输入法 自动 联想出,用户既省事,还能给厂家做广告,一举多得。
个人分类: 生活点滴|3172 次阅读|8 个评论
如何证明你是人——趣味Captcha
热度 1 xuyingxiao 2012-4-29 16:08
CAPTCHA(全自动区分计算机和人类的图灵测试),主要是为了防范有些人在论坛上通过软件自动发布垃圾信息,也可用于防止软件自动注册大量账号、搜集Email地址、在线投票中刷票、滥用搜索引擎、字典式猜测账号的密码等。 主要做法是让你做些事情,这些事情的特点是:真正的人很容易做,但按照当前的技术通过软件很难自动完成。 为了防止软件自动完成这些任务,人们想出了各种巧妙的任务,其中不乏发表在顶级国际会议的成果。 参见之前的博文: 新桃花源记(N)——你是人吗? ( http://blog.sciencenet.cn/home.php?mod=spaceuid=504160do=blogid=441759 ) 以下图片均搜集自网上或来自学术论文: 通过软件自动破解Captcha,可以卖个好价钱。 变形再变形,依旧免不了被破解,得想些新法子。比如识别中国的草书。 科学网的Captcha(早期是让大家做科学题目,后来改成传统的输入字符了) 传统的Captcha 识别出扭曲的字符后,需要通过鼠标拖动来输入。 拖动滑块旋转图片把图片放正(这可是发表在顶级国际会议上的成果) 下面哪句话是更加自然(不是机器翻译的)? 智力测试 专业题目 利用视觉错误
个人分类: 科普|5210 次阅读|4 个评论
[转载]自动识别图形验证码Java(转载)
dongzg101 2012-3-4 17:17
自动识别图形验证码Java(转载) xinxingwu 发短消息 加为好友 xinxingwu 当前离线 最后登录 2012-3-4 注册时间 2008-5-17 威望 107 活跃度 117344 ℃ 金币 2481 枚 积分 2856 精华 97 帖子 520 主题 167 版主 楼主 发表于 3天前 | 只看该作者 | 倒序浏览 | 打印 | 阅读权限 10 .pcb{margin-right:0} 本帖最后由 xinxingwu 于 2012-3-1 10:38 编辑 现在大多数网站都采用了验证码来防止暴力破解或恶意提交。但验证码真的就很安全吗?真的就不能被机器识别?? 我先讲讲我是怎么实现站外提交留言到一个网站的程序。 这个网站的留言版大致如下: 我一看这种简单的4位数字验证码,马上就感觉到有戏了。直觉告诉我让电脑来识别这些图片验证码据对简单o(∩_∩)o... 首先我马上在这个页面用右键菜单看源代码 知道验证码获取页面后 你可以直接用 http://www.XXXX.com/imgchk/validatecode.asp 这样去访问你会发现你打开的就是一个验证码图片。 对的其实返回的就是图片文件的2进制流而已。接着先用右键保存一张验证码的图片。因为要开始分析这张图片了,什么用什么工具?PhotoShop????不用就一般的画图工具就可以了。我们要搞清楚的是 这几个数字分别占几个像素就可以了。 可以看出 一个数字5*9 也就是45个像素。恩 这就可以了 另外我们可以看出 默认区域就是白色 (姑且说是白色因为我们肉眼看就是白色) 那么我的程序识别原理就是固定去扫描这45个像素点。看每个点的颜色是不是和默认的颜色一致 一致的话就标记为0 ,不一致就标记为1 。 如一个数子是2 那么我的程序扫描出来的图像就应该是: 011110 100001 000001 000001 000010 000100 001000 010000 100000 111111 如果一个数字是7那么扫描出来的图像就是: 111111 100001 000010 000010 000100 000100 001000 001000 010000 010000 恩,就这么简单呵呵。下面给出图像 扫描的java类 (不好意思,在我会的语言里面除开java就剩sql了) package com.util; //~--- JDK imports ------------------------------------------------------------ import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGEncodeParam; import com.sun.image.codec.jpeg.JPEGImageEncoder; import java.awt.*; import java.awt.image.*; import java.io.*; import java.io.FileOutputStream; import java.io.OutputStream; import java.net.*; import javax.imageio.*; import javax.imageio.ImageIO; /** *//** * 登陆验证图片转换为数字 * * * @version 1.0, 08/04/20 * @author 张健滢 */ public class ImgIdent ...{ // 数字字符比特表 private final long NUMERIC = ...{ ...{ 512104545, 562436190 }, // ''0'' ...{ 148931080, 136348222 }, // ''1'' ...{ 511971394, 69273663 }, // ''2'' ...{ 511971406, 17045598 }, // ''3'' ...{ 35168914, 586948743 }, // ''4'' ...{ 1065486398, 17045598 }, // ''5'' ...{ 239208494, 830871646 }, // ''6'' ...{ 1065623684, 69239824 }, // ''7'' ...{ 512104542, 562436190 }, // ''8'' ...{ 512104547, 486805660 } }; // ''9'' // 字框高 private int intCharHeight = 10; // 字框横向间隙 private int intCharSpaceH = 5; // 字框纵向间隙 private int intCharSpaceY = 1; // 字框宽 private int intCharWidth = 5; private int IntImgHeight; private BufferedImage img; private int intBgColor; private int intCharColor; private int intImgWith; private int intMaxX; private int intMaxY; private int intMinX; private int intMinY; // 座标原点 private Point pOrigin; private String strNum; /** *//** * Constructs ... * * * @param img * * @throws IOException */ public ImgIdent(BufferedImage img) throws IOException ...{ this.img = img; init(); } /** *//** * 构造函数 * @param file 本地文件 * @throws IOException */ public ImgIdent(File file) throws IOException ...{ img = ImageIO.read(file); init(); } /** *//** * 构造函数 * @param url 远程文件 * @throws IOException */ public ImgIdent(URL url) throws IOException ...{ img = ImageIO.read(url); init(); } /** *//** * 类初始工作 */ private void init() ...{ // 得到图象的长度和宽度 intImgWith = img.getWidth(); IntImgHeight = img.getHeight(); // 得到图象的背景颜色 intBgColor = img.getRGB(7, 4); // System.out.println(intBgColor); // 初始化图象原点座标 pOrigin = new Point(0, 0); } /** *//** * Method description * */ private void getBaseInfo() ...{ System.out.println(intBgColor + "|" + intCharColor); System.out.println(intMinX + "|" + intMinY + "|" + intMaxX + "|" + intMaxY); } /** *//** * 得到字符的左上右下点座标 * @param intNo int 第n个字符 * @return int getCharRange(int intNo) ...{ // 左上右下点座标 Point pTopLeft = new Point(0, 0); Point pBottomRight = new Point(0, 0); // 左上点 pTopLeft.x = pOrigin.x + intCharWidth * (intNo - 1) + intCharSpaceH * (intNo - 1); pTopLeft.y = pOrigin.y; // 右下点 pBottomRight.x = 1 + pOrigin.x + intCharWidth * intNo + intCharSpaceH * (intNo - 1) - 1; pBottomRight.y = pOrigin.y + intCharHeight - 1; return new Point " + intCurtColor + "==" + intBgColor + "==" + (Math.abs(intCurtColor) 7308252)); // return (Math.abs(intCurtColor) = 5689325) // ? ''0'' // : ''1''; return (intCurtColor == intBgColor) ? ''0'' : ''1''; // 5689325 6008535 } /** *//** * 得到第n个字符对应的字符串 * @param intNo int 第n个字符 * @return String 代表字符位的串 */ private String getCharString(int intNo) ...{ // 本字符的左上右下点座标 Point ; Point pBottomRight = p ; // 换算边界值 int intX1, intY1, intX2, intY2; intX1 = pTopLeft.x; intY1 = pTopLeft.y; intX2 = pBottomRight.x; intY2 = pBottomRight.y; // System.out.println("intX1=" + intX1); // System.out.println("intY1=" + intY1); // System.out.println("intX2=" + intX2); // System.out.println("intY2=" + intY2); // 在边界内循环取象素 int i, j; String strChar = ""; for (i = intY1; i = intY2; i++) ...{ for (j = intX1; j = intX2; j++) ...{ System.out.print(getBit(j, i)); strChar = strChar + getBit(j, i); } System.out.println(); } System.out.println(); return strChar; } /** *//** * 得到第n个字符对应数值 * @param intNo int 第n个字符 * @return int 对应数值 */ public int getNum(int intNo) ...{ // 取得位字符串 String strChar = getCharString(intNo); // System.out.println(intNo+"=="+strChar); // 取得串高位串和低位串 String strCharHigh = strChar.substring(0, strChar.length() / 2); String strCharLow = strChar.substring(strChar.length() / 2); // 计算高位和低位值 long lCharHigh = Long.parseLong(strCharHigh, 2); System.out.println(lCharHigh); long lCharLow = Long.parseLong(strCharLow, 2); System.out.println(lCharLow); // 在数字中循环比较 int intNum = ''*''; for (int i = 0; i = 9; i++) ...{ if ((lCharHigh == NUMERIC ) (lCharLow == NUMERIC )) ...{ intNum = i; break; } else ...{ if ((lCharHigh == 834533329) (lCharLow == 242870177)) ...{ intNum = 6; } // 834533329 242870177 else ...{ intNum = 1; } // 默认为1 低位为 937393609 937393601 } } return intNum; } /** *//** * 保存图片 * * * @param length * * @return */ public String getValidatecode(int length) ...{ String strNum = ""; for (int i = 1; i = length; i++) ...{ synchronized (this) ...{ strNum += String.valueOf(getNum(i)); } } return strNum; } /** *//** * Method description * * * @param iag * @param savePath * * @throws FileNotFoundException * @throws IOException */ public void saveJPEG(BufferedImage iag, String savePath) throws FileNotFoundException, IOException ...{ OutputStream jos = new FileOutputStream(savePath); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(jos); JPEGEncodeParam jpegEP = JPEGCodec.getDefaultJPEGEncodeParam(iag); jpegEP.setQuality((float) 1, true); encoder.encode(iag, jpegEP); jos.flush(); jos.close(); } } 恩这样数字是可以识别出来了,可以我要怎么完成提交那块的工作呢?好在Apache已经为我做完了。我用了 HttpClient这样一个模拟Http协议的小工具包。我只要往那个 Add_MSG.asp里面提交就完了。 package com.util; //~--- non-JDK imports -------------------------------------------------------- import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.params.HttpClientParams; import org.apache.commons.httpclient.params.HttpMethodParams; //~--- JDK imports ------------------------------------------------------------ import java.awt.image.BufferedImage; import java.io.InputStream; import javax.imageio.ImageIO; public class MyHttpClient ...{ /** *//** * Method description * * * @param title 留言标题 * @param name 留言者 * @param Content 内容 * @param proIP 代理IP * @param port 代理端口 * @param usePro 是否使用代理 */ public synchronized void doSomeThing(String title, String name, String Content, String proIP, int port, boolean usePro) ...{ // 构造HttpClient的实例 HttpClient httpClient = new HttpClient(); HttpClientParams clientParams = new HttpClientParams(); // 隐藏自己请求相关的信息 clientParams.setParameter("http.useragent", "Mozilla/4.0 (compatible; FIREFOX 9.0; IBM AIX 5)"); // httpClient.getHttpConnectionManager().getParams().setSoTimeout(30 * 1000); clientParams.setHttpElementCharset("GBK"); HttpState httpState = new HttpState(); httpClient.setParams(clientParams); httpClient.getParams().setParameter(HttpClientParams.HTTP_CONTENT_CHARSET, "GBK"); httpClient.setState(httpState); clientParams.setVersion(HttpVersion.HTTP_1_1); // httpClient.getHostConfiguration().setProxy("148.233.159.58", 3128); if (usePro) // 使用代理 ...{ httpClient.getHostConfiguration().setProxy(proIP, port); } // 创建GET方法的实例 GetMethod getMethod = new GetMethod(" http://www.XXXcom/Guestbook/imgchk/validatecode.asp "); // 使用系统提供的默认的恢复策略 getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler()); try ...{ // 执行getMethod int statusCode = httpClient.executeMethod(getMethod); // System.out.println(statusCode); if (statusCode != HttpStatus.SC_OK) ...{ System.err.println("Method failed: " + getMethod.getStatusLine()); } // 读取内容 InputStream inStream = getMethod.getResponseBodyAsStream(); // 处理内容 // System.out.println(new String(responseBody)); BufferedImage iag = ImageIO.read(inStream); ImgIdent imgIdent = new ImgIdent(iag); // imgIdent.saveJPEG(iag, "C:/ddd.jpg"); String validate = imgIdent.getValidatecode(4); System.out.println(validate); PostMethod method = new PostMethod(" http://www.XXX.com/Guestbook/add_msg.asp "); String connect = Content; String Title = title; method.setParameter("subject", Title); method.setParameter("g_name", name); method.setParameter("companyname", ""); method.setParameter("mail", ""); method.setParameter("homepageurl", "http://"); method.setParameter("pic", "p5.gif"); method.setParameter("validatecode", validate); method.setParameter("content", connect); // if (todo) { int code = httpClient.executeMethod(method); // String Stringresponse = new String(method.getResponseBodyAsString().getBytes("8859_1")); // 打印返回的信息 // System.out.println(Stringresponse); // } method.releaseConnection(); // System.out.println(iag.getHeight()); // System.out.println(iag.getWidth()); // //背景 颜色 // intBgColor = iag.getRGB(38, 0); // System.out.println("intBgColor=" + intBgColor); // // // intBgColor = iag.getRGB(0, 0); // System.out.println("intBgColor=" + intBgColor); } catch (Exception e) ...{ // 发生网络异常 e.printStackTrace(); } finally ...{} // 释放连接 getMethod.releaseConnection(); } getMethod.releaseConnection(); } } 恩 就这样了,最后结合SAF整成这样了。什么?为什么不用SWT?想过了SWING才是王道o(∩_∩)o... 文章出处: http://www.diybl.com/course/3_program/java/javashl/2008426/111563.html
个人分类: 茶余饭后|4790 次阅读|0 个评论
请科学网编辑部关注博客评论的“验证码”:它经常不工作!
热度 3 HeYujian 2011-5-16 23:52
请科学网编辑部关注“验证码”麻烦:经常不工作! 至少我的博客如此 。最近我的网友只能将他们的评论以电话短信或电子邮件方式发给我,由我再上传到网上。搞得大家都很烦燥。 我试了一下,如作为游客由于验证码问题也贴不上评论。填最大的字符,啥意思?试哪个都不工作,呵呵,故意让人生气? 请编辑部关注此问题。另建议验证码以数字与英文字母较为简单,不要用汉字。以前博客老版本系统的验证码就很好用。 谢谢啦!唉。。。
个人分类: 随思随想|3717 次阅读|8 个评论
什么是科学?请看科学网的“验证问题”和“验证码”
热度 10 wangxh 2011-3-23 12:27
什么是科学?请看科学网的“验证问题”和“验证码”! 今天科学网的又开始使用“验证码”,而且把门更严,多了一道知识问答“验证问题”,这叫绝呀!简直太绝了,这才是科学网的举措,这才有科学特色嘛! 不过搞的俺挺紧张的,因为万一弄不好就担心回不了自己的家呀! 今天遇到两只拦路虎: 第一,“日心说”的哥白尼。这种游戏都扔多少年了,早就不玩了,突然看见着实有些发懵,结果一不小心写上了“布鲁诺”,结果得一个红 X 。马上反映过来,布鲁诺不是因为捍卫真理被那个了吗?他老人家怎么能够通过验证呢,赶紧填写白尼哥才得以回家。 第二,刚才吃完午饭回来,打算上来看看,结果“76.1年轮回的彗星”出来问口令,还注明四字。小时候听说,看见彗星不吉利,虽然知道是瞎说,但俺还是宁愿不碰上彗星。但是太白金星又不出现,打不上问题,哈老爷肯定不让进家门的。这招儿最高,俺估计那广告机累死也猜不中哈老爷打更的喽! 因此,俺们应该艰苦朴素、力争上游、多快好省地建设具有科学特色的科学网(博客)! 并且建议:长期保留集知识性、趣味性及脑筋急转弯性于一体的“验证问题”,一方面可以科普,一方面可以复习科普,还能踢出“滥竽充数”的科学人!
个人分类: 未分类|5104 次阅读|13 个评论
发博文应该方便并节省时间
lhj701 2011-3-5 10:58
发博文应该方便并节省时间 (罗汉江) 今天突然发现科学网发博文、评价不用加 验证码 之类的东东了。原来我就想,既然 科学网博主是实名,登陆后相当于身份验证过 了,再来1-2篇验证,难道为了防止黑客盗取博主身份不成?但又没有办法,只好填过几遍后方可发文、评论,额外耗费许多精力。 现在终于又恢复原来的方便,希望这不是暂时的,而只要没有安全问题还是多从方便和省时角度想想。呵呵。
个人分类: 观点建议|2610 次阅读|0 个评论
统计学是工具更是方法
montec007 2011-3-1 22:31
对孙学军老师博文《不要迷恋统计学》的一点补充:统计学不但是工具,更是研究方法。 研究方法分为归纳和演绎,统计学几乎是归纳法的全部内容。 经验科学(Empirical Sciences)的主要特点就是从噪音中寻找真谛,因此,统计学不是一种“迫不得已的工具”,而是科学研究的必需,它具体体现在假设检验上。任何一项科学试验都是建立在假设(是Hypothesis,而不是assumptions)的基础上,试验的主要目的就是证伪(falsify)这个假设——这也是波普尔科学哲学的核心思想。 近代历史德国人雄于思辨,成就了许多哲学大家;英国人强于观察和归纳,成就了日不落帝国的几百年辉煌;现代中国呢,似乎陷于工具中不可自拔,所以高铁、机场、政府房、核电站、风电场都在盲目疯狂地兴建。 God does not only play dice, but play in the dark.
个人分类: 研究方法|3081 次阅读|0 个评论
关于启用验证码功能的说明
科学网编辑部 2011-3-1 16:17
尊敬的用户: 近日论坛、博客出现大量带有广告内容的评论,为此论坛、博客暂时启用验证码功能。 由于技术所限,在个别情况下,发表博文评论时也会提示需要填写验证码。给您带来不便深感歉意。 我们正在积极寻找解决办法,待问题解决后,验证码设置将会取消。
个人分类: 通知公告|4719 次阅读|0 个评论
】科学网【 建议改进验证码
热度 2 metanb 2011-3-1 12:59
评论可以加验证码,发博文就不必用验证码了,毕竟都是实名用户。
个人分类: 公共事物|2247 次阅读|4 个评论
¥科学网¥:可恶的验证码
热度 2 metanb 2011-3-1 09:41
验证码,麻烦大大地。
个人分类: 魔鬼辞典|1811 次阅读|1 个评论
怎么突然多了个“验证码”呀?——已经搞明白了!
热度 7 wangxh 2011-2-28 12:29
俺已经明白了为什么加“验证码”! 为了防止刷贴。要是没有验证码,用机器可以无限制刷贴。
个人分类: 未分类|2454 次阅读|10 个评论
相关博文栏目干脆关了?
热度 2 wliming 2011-2-28 10:37
我前几天向科学网报告,相关博文栏目列出的是不相关的博文。编辑部认为没发现问题。但我感到,这个相关博文还是有问题。不知是不是关键词的数据库不对应的原因。 现在怎么连这栏目都没了? 另外,现在加的这个验证码够狠,让老人家连猜带蒙都很难过关。什么人创造的这些垃圾验证码啊? 注:好像不是全部博文都没有相关博文栏目。
个人分类: 娱乐|1130 次阅读|2 个评论
验证与破解的博弈
creator 2010-5-11 22:39
现在很多软件或网站都有验证码及数字签名等验证方式,但是脱壳,图像识别破解也在大行其道。 验证码及一些验证技术主要是为了防止机器人,在博客及评论模式热起来以后,很多人利用这个平台来打广告,甚至破坏正常的留言,比如科学网的留言系统就有很大漏洞,首先匿名留言的验证码容易破解,其次可以注册用户机器留言,这是一个容易受攻击的模式。 先看下为了防止机器人破解,大家都相出了什么招式: 来源: http://cn.engadget.com/2008/09/02/15-bt-captcha/ 1, 数学类 简单的加减乘除就不列举出来。 这种验证码的好处是需要一定的数学水平,可以较为有效的防止未成年人的进入,一般而言,未成年人都不能解答出上述结果。但缺点是比较费时。 比较适合成人网站验证,但是对于不懂数学的色狼是个问题。 2,扭曲型 采用不同字体及变形模糊效果是比较常用的办法。有效度70%以上,一般的识别软件都只能准确识别30%左右,但有时人也会识别错误。 当然这其中也包含很难辨别的内容。 3,化学知识或其他知识 一般包含各专业知识,很多专业的论坛都会提一些专业的问题,以防止机器人侵扰。 4,背景影响类型,跟第三种有类似的地方,但是能引起误识别,而不是普通的干扰背景。包括GIF动画类。 5,图形二次替代 这种图形的识别可以做到很难,而且需要替换理解。破解较难。这种值得提倡,简单高效。 6,特殊知识类型 这个需要较强的空间想象力,而且有时间限制。当然这里也可以借助图论,拓扑学,智力测试题里的一些东西来验证。比较变态。适合高难度的论坛注册,考考你智商够不够,不够格就不能加入。 这种类型的可以扩展成很复杂的验证识别,比如验证识别是时间限制的智力题或者下棋,如果没有较强的专业知识,是不可能破解的。假设将这种识别方式放在保险柜的识别上,而用户是一个五子棋或象棋爱好者,那么设置定时棋局,那么没有水平是不能打开这个保险柜的。甚至将一盘围棋的棋谱作为验证方式。 7,图形或情感验证 这是一种情感认知的验证,除了采取统计破解方法有点希望外,很难破解。 这里可以拓展一种方式,即人像识别的方式。比如以爱因斯坦的头像为例: 假设爱因斯坦,特斯拉和爱迪生的图片代表不同的数字或字母,那么提问可以是先爱因斯坦后特斯拉这样排列的字母数字组合是什么?为了防止统计识别,可以如爱因斯坦的红蓝框所示,每次随机截取分块,或者在图上随机破坏一块信息,比如扭曲,替换等方式,这样不影响人的识别,但是会影响统计破解。剩下的唯一一条破解路是图像识别了。 如下验证码基本能被破解了,很多OCR软件相当的厉害了: (图片来自网络) 所以要采取更高级的验证码。 验证码与图像识别的博弈,胜的一方常常是验证码。 毕竟图像识别的准确率还不高,比如汽车牌照,人像识别都还有待提高。图像识别问题没有完全解决,那么验证码就可以大行其道,使得验证码始终占据博弈上风。 利用这种方式来加密: 在我以前的博文有提到过,因为现在的破解都是靠计算机的高速破解计算而获得,即Bruce暴力破解居多,这样越是先进的计算机就越占便宜。所以很多黑客及过滤设备就能解密过滤,以达到截获信息的目的。现在假设每次解密或破解都必须人工输入验证码会怎样呢?所有的破解装置会变成破铜烂铁。实现方式就是将密文转化为验证码并二次加密,比如先用AES加密,然后将密文的一段转化为验证码,然后将验证码的二进制码插入密文二进制码中,混合再用一种加密方式加密。这样即使先把后一种加密破解了,也面临人工识别验证码并输入信息的过程,这一过程计算机无法自动完成。所以整个解密过程必须人工干预,这样其将无法通过自动破解来获得信息内容。黑客及不法分子在实际的信息拦截过程中,面对是海量的信息,采取的是随机或指定抓包来提取,即便如此也是要处理很多信息,如果要人工干预,破解量将相当有限。但是这样也会给使用者带来麻烦,会增加操作复杂性及计算耗费。 但是能带来很大安全性,比如瑞星杀毒在卸载时会输入验证码,某些权限的实施需要有人工识别过程,以免机器人或病毒破坏。特别是一些高级权限为了防止截取或非法操作,使用这些验证过程可大大提高安全性。 除加密软件外,其他软件也可以采用这种方式来加密或注册验证,在脱壳的过程中需要考虑验证问题时就会增加难度,或者在线注册时就可以减少欺骗和机器人干预。 保险柜,门禁等就可以量身定做,根据客户的特点来定制加密模式,比如采取游戏胜负验证加普通密码验证,但是对设备要求会很高。 最大的用途还是在网络传输及远程权限设置等环节,这些领域有更好的安全性才行,加了更多高级的验证码验证机制比普通的VPN+ssl模式更安全。
个人分类: 科学|2202 次阅读|0 个评论
ASP.NET验证码(3种)
cai7net 2008-6-26 10:39
ASP.NET验证码(3种) 2007年12月17日 星期一 12:06 ASP.NET验证码(3种) 把最近碰到的 能够用的验证码 都放出来,作个记录 1.GSC_WebControlLibrary 这是在网上找到的一个控件,非常好用。但是效果不是特别好(见下图。 )虽然容易使用,所有的属性都可以像控件一样设置,但是可用性不太高。用户不能自定义,而且看起来这个验证码效果不太好。 效果: 2.用一个页面生成图片,另一个页面调用,验证码存入cookie,调用时取cookie对比验证.这个用户就可以按自己的喜好更改效果和验证码的长度了 (: 效果如图: 代码如下: CheckCode.aspx using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; public partial class Tools_CheckCode : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { this.CreateCheckCodeImage(GenerateCheckCode()); } private string GenerateCheckCode() { int number; char code; string checkCode = String.Empty; System.Random random = new Random(); for (int i = 0; i 5; i++) { number = random.Next(); if (number % 2 == 0) code = (char)('0' + (char)(number % 10)); else code = (char)('A' + (char)(number % 26)); checkCode += code.ToString(); } Response.Cookies.Add(new HttpCookie(CheckCode, checkCode)); return checkCode; } private void CreateCheckCodeImage(string checkCode) { if (checkCode == null || checkCode.Trim() == String.Empty) return; System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22); Graphics g = Graphics.FromImage(image); try { //生成随机生成器 Random random = new Random(); //清空图片背景色 g.Clear(Color.White); //画图片的背景噪音线 for (int i = 0; i 25; i++) { int x1 = random.Next(image.Width); int x2 = random.Next(image.Width); int y1 = random.Next(image.Height); int y2 = random.Next(image.Height); g.DrawLine(new Pen(Color.GreenYellow), x1, y1, x2, y2); } Font font = new System.Drawing.Font(Verdana, 12, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic)); System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true); g.DrawString(checkCode, font, brush, 2, 2); //画图片的前景噪音点 for (int i = 0; i 80; i++) { int x = random.Next(image.Width); int y = random.Next(image.Height); image.SetPixel(x, y, Color.FromArgb(random.Next())); } //画图片的边框线 g.DrawRectangle(new Pen(Color.Red), 0, 0, image.Width - 1, image.Height - 1); System.IO.MemoryStream ms = new System.IO.MemoryStream(); image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); Response.ClearContent(); Response.ContentType = image/Gif; Response.BinaryWrite(ms.ToArray()); } finally { g.Dispose(); image.Dispose(); } } } 然后在需要使用的页面引用: UseCheckCode.aspx img src=Tools/CheckCode.aspx alt=验证码 style=width: 60px; height: 24px / 3.用web handler生成图片。这个其实和前面的意思大致差不多,调用方法也基本和2一样,不同的是,他的验证码是存入Session的。供学习参考。 效果图如下: ValidateImageHandler.ashx %@ WebHandler Language=C# Class=ValidateImageHandler % using System; using System.Web; using System.Web.SessionState; using System.Drawing; using System.Drawing.Imaging; using System.Text; /**//// summary /// ValidateImageHandler 生成网站验证码功能 /// /summary public class ValidateImageHandler : IHttpHandler, IRequiresSessionState { int intLength = 5; //长度 string strIdentify = Identify; //随机字串存储键值,以便存储到Session中 public ValidateImageHandler() { } /**//// summary /// 生成验证图片核心代码 /// /summary /// param name=hc/param public void ProcessRequest(HttpContext hc) { //设置输出流图片格式 hc.Response.ContentType = image/gif; Bitmap b = new Bitmap(200, 60); Graphics g = Graphics.FromImage(b); g.FillRectangle(new SolidBrush(Color.YellowGreen), 0, 0, 200, 60); Font font = new Font(FontFamily.GenericSerif, 48, FontStyle.Bold, GraphicsUnit.Pixel); Random r = new Random(); //合法随机显示字符列表 string strLetters = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890; StringBuilder s = new StringBuilder(); //将随机生成的字符串绘制到图片上 for (int i = 0; i intLength; i++) { s.Append(strLetters.Substring(r.Next(0, strLetters.Length - 1), 1)); g.DrawString(s .ToString(), font, new SolidBrush(Color.Blue), i * 38, r.Next(0, 15)); } //生成干扰线条 Pen pen = new Pen(new SolidBrush(Color.Blue), 2); for (int i = 0; i 10; i++) { g.DrawLine(pen, new Point(r.Next(0, 199), r.Next(0, 59)), new Point(r.Next(0, 199), r.Next(0, 59))); } b.Save(hc.Response.OutputStream, ImageFormat.Gif); hc.Session = s.ToString(); //先保存在Session中,验证与用户输入是否一致 hc.Response.End(); } /**//// summary /// 表示此类实例是否可以被多个请求共用(重用可以提高性能) /// /summary public bool IsReusable { get { return true; } }
个人分类: ASP.NET|598 次阅读|0 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-21 08:00

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部