一、主要作用:
现在很多网站使用验证码技术,主要为了安全性考虑,防止用户使用程序自动机进行自动提交注入,避免服务器交互处理遭受不必要的攻击。其主要思想是必须通过人为参与完成信息提交过程,并且对验证码字体做了相关处理,因为对于目前的技术发展来说,验证码的计算机自动识别还不太容易(不是没有可能)。虽然现在有些技术可以绕过验证码输入这一关,但使用验证码技术,也还是对其有一定的制约作用,并且主要的对网站的信息安全还是起到了显著的保护屏障的作用。
二、技术原理:
验证码的实现方法有很多种,但大致模式是一样的。目前有的网站使用验证码的方式有session方式和cookie方式,区分主要根据验证码初始值保存在哪里,虽然对于一般用户而言这两种都是不可见的,但安全性差别很大。一般而言,session方式比较安全,用户除非识别图片,别无选择,只是增加了服务器的一丁点额外的内存消耗。cookie方式不使用额外的服务器内存,但cookie方式用户可对验证交互过程数据进行分析,可轻松破解验证码,所以出于更高的安全性考虑,还是建议使用session方式。验证码的使用很简单,只是在原有表单提交代码内加入两个新要素:验证码输入框,验证码图片。验证码图片,图片源指向服务器端动态处理,输出二进制图片格式,用户看不清时可单独重载图片,产生新的验证码。验证码输入,主要用于用户获取用户识别验证码图片的结果。提交数据后服务器根据已保存的初始值和用户识别值进行比对,如不符,立即停止信息提交处理,反馈验证码输入错误通知。
三、实例解析:
java验证码实现组件:
import java.awt.*;
import java.awt.image.*;
import java.io.*;
......
public class ValidateCode{
HttpServletRequest request=null;
HttpServletResponse response=null;
String validate_rnd=null;
public ValidateCode(HttpServletRequest request1,HttpServletResponse response1){
this.request=request1;
this.response=response1;
this.validate_rnd=CookieEx.getCookie(this.request,"validate_rnd");//String.valueOf(System.currentTimeMillis());
}
public void init(){
CookieEx.setCookie(response,"validate_rnd",this.validate_rnd);
}
public static void outputImage(HttpServletRequest request1,HttpServletResponse response1){
ValidateCode vc=new ValidateCode(request1,response1);
vc.validate_rnd=String.valueOf(System.currentTimeMillis());
vc.init();
String validate_code=vc.getValidateCode();
try{
vc.response.setContentType(SystemConfig.getParameter(".png"));
createImagePNG(validate_code,vc.response.getOutputStream());
}catch(Exception e){}
}
public String getValidateCode(){
String tmp=this.validate_rnd+this.request.getSession().getId();
tmp=MD5.encode(tmp+String.valueOf(tmp.hashCode())).toUpperCase();//对产生字符串做单向加密处理
tmp=StringEx.replace(tmp,"O","0");//把字母O转换成数字0
return new String(new char[]{tmp.charAt(1),tmp.charAt(3),tmp.charAt(5),tmp.charAt(7)});//获取制定位置的字符值
}
public boolean verifyValidateCode(String input_code){
if(input_code==null||input_code.equals(""))return false;
input_code=input_code.toUpperCase();//统一大小写
return getValidateCode().equals(StringEx.replace(input_code,new String[]{"o","O"},new String[]{"0","0"}));//防止歧义,把字母O转换成数字0
}
public static void createImagePNG(String signcode,OutputStream out){
BufferedImage offimg=null;
Graphics offgra=null;
while(offimg==null||offgra==null){
if(offimg==null)offimg=new BufferedImage(50,18,BufferedImage.TYPE_INT_RGB);
if(offgra==null&&offimg!=null)offgra=offimg.getGraphics();
}
offgra.setColor(new Color(235,235,235));
offgra.fillRect(0,0,50,18);
/*for(int i=0;i<12;i++){//生成混淆背景,也可用混淆背景图片
offgra.setColor(Color.decode("#"+color[SystemTool.getRandom(0,color.length-1)]));
offgra.fillOval(SystemTool.getRandom(0,48),SystemTool.getRandom(0,18),1,1);//10,4);
}*/
offgra.setColor(Color.red);
//offgra.setColor(Color.decode("#"+color[SystemTool.getRandom(0,color.length-1)]));
offgra.drawString(signcode,1,14);
PngEncoder png=new PngEncoder(Toolkit.getDefaultToolkit().createImage(offimg.getSource()),PngEncoder.ENCODE_ALPHA,PngEncoder.FILTER_LAST,3);
try{out.write(png.pngEncode());}catch(Exception e){}
offgra.dispose();
}
}
Java验证码组件使用:
图片源动态处理:
<%@page contentType="image/gif"%><%@page import="java.util.*,......"%><%
response.setHeader("Pragma","No-cache");
response.setDateHeader("Expires", 0);
ValidateCode.outputImage(request,response);
%>
服务器信息提交验证:
<%
......
if(new ValidateCode(request,response).verifyValidateCode(request.getParameter("user_validate_code"))){
msg+="验证码正确";
......//信息提交处理
}else{
msg+="验证码错误";
}
......
%>
以上讲述了有关验证码的作用和技术原理以及实例分析,如有疑问的朋友,请到论坛发帖。
软件人才网,找不找工作都来逛逛。