验证码是怎样生成的

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2
//产生随机数 Random rnd = new Random(); int randNum = rnd.nextInt() + 1000; String randStr = String.valueOf(randNum); session.setAttribute("randStr", randStr); 4.用画笔画出随机数和干扰点。 g.setColor(Color.black); g.setFont(new Font("", Font.PLAIN, 20)); g.drawString(randStr, 10, 17); //随机产生 100 个干扰点,使图象中的验证码不易被其他程序探测到 for (int i = 0; i < 100; i++){ int x = rnd.nextInt(width); int y = rnd.nextInt(height); g.drawOval(x, y, 1, 1); } 5.输出图像。 // 输出图象到页面 ImageIO.write(Image image, "JPEG", response.getOutputStream()); 6.清除缓冲区。 out.clear(); out = pageContext.pushBody(); 下面通过 6 个步骤在 JSP 页面生成验证码: validate.jsp <%@ page language="java" import="java.awt.*" import="java.awt.image.BufferedImage" import="java.util.*" import="javax.imageio.ImageIO" pageEncoding="gb2312"%> <% response.setHeader("Cache-Control","no-cache"); // 在内存中创建图象 int width = 60, height = 20; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); //获取画笔 Graphics g = image.getGraphics(); //设定背景色 g.setColor(new Color(200, 200, 200)); g.fillRect(0, 0, width, height); //取随机产生的验证码(4 位数字) Random rnd = new Random(); int randNum = rnd.nextInt(8999) + 1000; String randStr = String.valueOf(randNum);
1 使用 JSP 验证码
1.1 为什么需要验证码
为什么需要验证码呢?首先来看下面这张图片,如图 1 所示:
图 1 含有验证码的表单
上面是某系统的登录页面。从页面上可以看出,似乎可以通过账号和密码来进行验证, 但是,页面上出现了一个新的输入项:验证码。 验证码有什么作用呢?假想该系统没有验证码, 直接通过用户名和密码登录, 那么就有 可能有恶意的用户不停输入用户名和密码进行登录试探,或者他使用一个输入程序(俗称机 器人程序)不停登录,有理由相信总有一天他是能够破解密码的,就可以使用别人的账号了。 或者即使他没有破解,只是不停的在登录,服务器每次都会验证数据库,也会严重的降低服 务器的效率,导致其他人不能使用。但是有了验证码之后,就可以避免这种现象。如图 2 所示:
1
1.2 验证码原理
验证码为什么可以防止对网站的恶意访问呢?首先介绍验证码必须满足以下几个性质: 1. 不同的请求,得到的验证码应该是随机的,或者是无法预知的,必须由服务器端产 生。 2. 验证码必须通过人眼识别,而通过图像编程的方法编写的机器人程序在客户端运行, 几乎无法识别。 这就是验证码都比较歪斜或者模糊的原因, 否则就很容易通过图像处理算法 来识别。 3. 除了人眼观察之外,客户端无法通过其他手段获取验证码信息。这就是验证码为什 么用图片, 而不是直接用一个数字文本在页面上显示的原因, 因为客户端可能通过访问网页 源代码的方式获取验证码的内容。 最初的验证码,只是几个随机生成的数字。但是很快就有能识别数字的软件了;目前常 见的验证码是随机数字(有的系统也用随机文字)图片验证码,不过,目前也正在研究对验证 码的识别。 验证码的工作流程如下: 1. 服务器端随机生成验证码字符串,保存在内存中,并写入图片,将图片连同表单发 给客户端。 2. 客户端输入验证码,并提交给表单字相比较;如果相同,则继续进行表单所描述的操作(如登录、注册等);如果不 同,直接将错误信息返回给客户端。避免程序的继续运行以及访问数据库。 3. 系统生成的一个随机数,大多为数字和字母,或者是数字和字母的组合,然后生成 一张根据随机数来确定的图片,把随机数写入到 session 中,传递到要验证的页面;生成的 图片显示给客户端,并要求客户端输入该随机数内容,提交到验证页面,验证 session 的内 容和提交的内容是否一致。
图 2 验证码
因为每登录一次服务器,客户都需要提供一次验证码,而验证码每次都是不同的。所以 很难使用机器人程序反复登录, 因为机器人程序无法认识验证码。 这就是验证码强大的功能 所在。 所谓验证码,就是由服务器产生的一串随机数字或符号,形成一幅图片,图片应该传给 客户端,为了防止客户端用一些程序来进行自动识别,图片中通常要加上一些干扰象素,由 用户肉眼识别其中的验证码信息。客户输入表单提交时,验证码也提交给网站服务器,只有 验证成功,才能执行实际的数据库操作 验证码在网络投票、交友论坛、网上商城等业务中,经常用来防止恶意客户侵入、恶意 灌水、刷票等,在 Web 中有着重要的应用。
2 验证码开发
2.1 在 JSP 上实现验证码
在 JSP 上开发验证码步骤如下: 1.实例化 java.awt.image.BufferedImage 类。它的作用是访问图像数据缓冲区,或者说 就是对所要绘的图片对象进行访问。 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); width、height 表示的是产生图片的大小,BufferedImage.TYPE_INT_RGB 是指使用的颜 色模式为 RGB 模式(具体其他模式读者可以自己去了解)。 2.从 BufferedImange 中获取 Graphics 类对象(画笔),并设定相关属性。 Graphics g = image.getGraphics(); Graphics 提供了对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制。 g.setColor(Color color);//设置颜色 g.fillRect(int,int,int,int);//设置生成的图片为长方形 3.产生随机数,并将其存入 session 中。
ChinaSEI系列讲义(By郭克华)
验证码是怎样生成的
如果有文字等小错,请多包涵。在不盈利的情况下,欢迎免费传播。 版权所有.郭克华 本讲义经过修正、扩充,由清华大学出版社出版。 详细可查询 /51834 /product.aspx?product_id=20862469
4
图 4 含有验证码的登录系统
2.2 实现验证码刷新
验证码所生成的干扰因素的设定一直是一个非常难以平衡的问题, 因为如果干扰因素比 较小的话有些扫描程序可以扫描识别验证码, 如果干扰因素比较大的话就会影响用户的正常 肉眼识别。 一般情况下验证码的干扰因素都是设置的稍微复杂一点点, 当用户看不清楚的时 候可以通过刷新实现重新生成验证码。 验证码的刷新技术有很多中,一般使用 JavaScript 刷新验证码,最方便的方法是,点击 验证码图片,获得新的验证码。本例中使用 JavaScript 来刷新验证码: refresh.jsp <%@ page language="java" pageEncoding="gb2312"%> <html> <body> <script type="text/javascript"> function refresh(){ loginForm.imgValidate.src = "validate.jsp"; } </script> 欢迎登录鲜花订购系统<BR> <form name="loginForm" action="/Prj15/servlet/ValidateServlet"> 请您输入账号:<input type="text" name="account" /><BR> 请您输入密码: <input type="password" name="password" /><BR> 请输入验证码:<input type="text" name="code" size="10"> <img name="imgValidate" src="validate.jsp" onclick="refresh()"><BR> <input type="submit" value="登录"> </form> </body> </html> 访问 refresh.jsp 页面得到如图 5 所示:
3
//将验证码存入 session session.setAttribute("randStr", randStr); //将验证码显示到图象中 g.setColor(Color.black); g.setFont(new Font("", Font.PLAIN, 20)); g.drawString(randStr, 10, 17); // 随机产生 100 个干扰点,使图象中的验证码不易被其他程序探测到 for (int i = 0; i < 100; i++){ int x = rnd.nextInt(width); int y = rnd.nextInt(height); g.drawOval(x, y, 1, 1); } // 输出图象到页面 ImageIO.write(image, "JPEG", response.getOutputStream()); out.clear(); out = pageContext.pushBody(); %> 在浏览器中访问 validate.jsp 页面得到(当然读者的机器上获得的验证码不一定相同)如图 3 所示:
图 3 生产的验证码
刷新,获得不同的验证码。 但是验证码单独出现, 还没有起到安全保障的作用, 因为验证码还需要和表单提交组合 起来使用。 将验证码和登录组合起来使用的思想就是把验证码当作一张图片处理, 如下代码: loginForm.jsp <%@ page language="java" pageEncoding="gb2312"%> <html> <body> 欢迎登录鲜花订购系统<BR> <form action="/Prj15/servlet/ValidateServlet"> 请您输入账号:<input type="text" name="account" /><BR> 请您输入密码: <input type="password" name="password" /><BR> 验证码:<input type="text" name="code" size="10"> <!-- 将验证码当成图片处理 --> <img border=0 src="validate.jsp"> <input type="submit" value="登录"> </form> </body> </html> 访问 loginForm.jsp 页面即可得到如图 4 所示的效果:
相关文档
最新文档