网站验证码的技术原理和实例解析

来源:互联网 发布:夏谷人力资源软件 编辑:程序博客网 时间:2024/05/17 08:09
本文转自<href="http://www.soft-hr.com">软件人才网</a>
 

一、主要作用:
 
      现在很多网站使用验证码技术,主要为了安全性考虑,防止用户使用程序自动机进行自动提交注入,避免服务器交互处理遭受不必要的攻击。其主要思想是必须通过人为参与完成信息提交过程,并且对验证码字体做了相关处理,因为对于目前的技术发展来说,验证码的计算机自动识别还不太容易(不是没有可能)。虽然现在有些技术可以绕过验证码输入这一关,但使用验证码技术,也还是对其有一定的制约作用,并且主要的对网站的信息安全还是起到了显著的保护屏障的作用。

二、技术原理:
      验证码的实现方法有很多种,但大致模式是一样的。目前有的网站使用验证码的方式有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+="验证码错误"; 
}
......
%>

以上讲述了有关验证码的作用和技术原理以及实例分析,如有疑问的朋友,请到论坛发帖





软件人才网,找不找工作都来逛逛。