枫林在线论坛精华区>>程序设计 |
[49886] 主题: 用java生成附加码 |
作者: leaflet (Leaf) | ||
标题: 用java生成附加码 | ||
来自: 218.80.*.* | ||
发贴时间: 2003年04月17日 13:47:39 | ||
长度: 7733字 | ||
现在一些网站登陆的时候都需要用户添加附加码,这样是保护用户,防 止黑客通过野蛮攻击获得用户信息(用户名称和口令,以前我用java做过 一个野蛮攻击的程序来攻击一些网站来获得用户密码^_^)。下面例子是我 实现附加码的方法,希望能起到启发作用! 刚开始我想用applet来实现附加码,这个实现方案的优点是实现速度快 、图片的生成在客户端执行不必访问服务器;但是这个方案的最大缺点是 容易泄密(用户可以下载applet,通过反编译可以知道附加码的实现算法 ,进而可以通过蛮力攻击而进入系统),所以没有采用。 因为逻辑在客户端实现容易造成泄密,所以逻辑现实应该在服务器端来 实现,我采用了小服务servlet。下面是实现的源代码:Picture.java、C reateImage.java和CreateImage.jsp //读取服务器端的图片,在图片上画用户需要输入的附加码 package lqh.rmb.picture; import java.io.*; public class Picture{ final int key=43; final String error_format_int= "format of color is not rg b.sample \"212|232|0\""; final String error_color_input="format of color(num|num|n um): num in 0-255"; /**格式化输出数据**/ public String manage(String temp){ String returnStr=""; temp = encrypt(temp); byte[] by =temp.getBytes(); for(int i=0;i<by.length;i++){ returnStr=returnStr+(byte)by[i]+"|"; } return returnStr; } /**格式化输入数据**/ public byte[] disManage(String temp){ int len=0,index=0,i=0,first=0; while(( i=temp.indexOf("|",first))>-1){ len++; first=i+1; } byte[] by=new byte[len]; first=0; while(( i=temp.indexOf("|",first))>-1){ by[index]=Byte.parseByte(temp.substring(first,i)); index++; first=i+1; } return by; } /**随机生成四位的附加码**/ public String getRandom(){ int i1 = (int)(java.lang.Math.random()*10); int i2 = (int)(java.lang.Math.random()*10); int i3 = (int)(java.lang.Math.random()*10); int i4 = (int)(java.lang.Math.random()*10); return String.valueOf(i1)+String.valueOf(i2)+String.valueOf( i3)+String.valueOf(i4); } /**加密1:错位处理**/ public String encrypt(String randomStr){ String para=random()+randomStr.substring(0,1)+random()+rand om()+randomStr.substring(1,2); para= para+random()+randomStr.substring(2); return jiaMi(para); } /**得到随机数0-9之间**/ private String random(){ String temp = String.valueOf((int)(java.lang.Math.random()*1 0)); return temp; } /**加密2:加密处理,此方法可以自己修改**/ private String jiaMi(String str){ byte[] by = str.getBytes(); ByteArrayInputStream in = new ByteArrayInputStream(by); int ch; int index=0; byte[] temp = new byte[in.available()]; while((ch=in.read())!=-1){ temp[index]=(byte)(ch-key); index++; } ByteArrayInputStream ins = new ByteArrayInputStream(temp); DataInputStream inss=new DataInputStream(ins); try{ return inss.readLine();}catch(Exception e){return &quo t;";} } /**从给的数字里得到正确的数字**/ public String discrypt(String temp){ String para = jieMi(disManage(temp)); return para.substring(1,2)+para.substring(4,5)+ para.substri ng(6,8); } /**解密处理**/ private String jieMi(byte[] by){ ByteArrayInputStream in = new ByteArrayInputStream(by); int ch; int index=0; byte[] temp = new byte[in.available()]; while((ch=in.read())!=-1){ temp[index]=(byte)(ch+key); index++; } ByteArrayInputStream ins = new ByteArrayInputStream(temp); DataInputStream inss=new DataInputStream(ins); try{ return inss.readLine();}catch(Exception e){return " ";} } /**分解rgb格式的颜色 num|num|num**/ public int[] masterData(String temp){ int index_len=0,index=0,next_index=0; int[] return_arr=new int[3]; boolean break_error=false; if(getMax(temp,"|")==2){ while((index_len=temp.indexOf("|",next_index))&g t;-1){ if(getInt(temp.substring(next_index,index_len))==256){ break_error = true; }else{ return_arr[index]=getInt(temp.substring(next_index,ind ex_len)); next_index=index_len+1; index++; } if(break_error) break; } if(break_error){ return null; }else{ return_arr[index] = getInt(temp.substring(next_index)); return return_arr; } }else{ System.out.println(error_format_int+":"+temp); return null; } } private int getMax(String temp,String temp2){ int index=0,index_len=0,index_next=0; while((index=temp.indexOf(temp2,index_next))>-1){ index_len++; index_next=index+1; } return index_len; } private int getInt(String temp){ try{ return Integer.parseInt(temp); }catch(Exception e){ System.out.println(error_color_input+":"+temp); return 256; } } } 下面是一个Servlet来响应客户,返回给客户一个做好的图片: package lqh.rmb.picture; import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import java.awt.*; import java.awt.image.*; import java.awt.image.BufferedImage; import com.sun.image.codec.jpeg.*; import com.sun.image.codec.jpeg.JPEGCodec; public class CreateImage extends HttpServlet { static final private String CONTENT_TYPE = "text/html; ch arset=gb2312"; final String input_back_color_error="input rgb backcolor is error"; final String input_fore_color_error="input rgb forecolor is error"; private Picture pic = new Picture(); //Initialize global variables public void init() throws ServletException { } //Process the HTTP Get request public void doGet(HttpServletRequest request, HttpServletRespo nse response) throws ServletException, IOException { String queryNum = request.getParameter("Image"); String queryRgb=""; if(request.getParameter("Rgb")!=null){ queryRgb = request.getParameter("Rgb"); } response.setHeader("Cache-Control","no-store& quot;); response.setContentType("image/jpeg"); ServletOutputStream out=response.getOutputStream(); //jpg格式的背景色图片(于页面风格一样),宽3.6毫米,高1.8毫米 InputStream imageIn = new FileInputStream(new File("D:/ test.jpg")); JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(image In); BufferedImage image4 = decoder.decodeAsBufferedImage(); queryNum = pic.discrypt(queryNum); Graphics g = image4.getGraphics(); if(queryRgb.length()>1){ if(pic.masterData(queryRgb)!=null){ int[] arg = pic.masterData(queryRgb); g.setColor(new Color(arg[0],arg[1],arg[2])); } }else{ g.setColor(new Color(255,0,0)); } g.drawString(queryNum,0,13); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(image4); out.close(); } } 下面是一个jsp页面来验证结果: <%@ page contentType="text/html; charset=GBK" %> <%@ page import=" lqh.rmb.picture"%> <% Picture pic = new Picture(); String random =pic.getRandom(); String encryRandom= pic.manage(random ); %> <html> <body> <%--这段代码可能需要自己来修改,才能调用到servlet--%> <img align=absbottom vspace=2 border=0 src="servlet/lqh. rmb.picture.CreateImage?Image=<%=encryRandom%>&Rgb=255 |0|0" title="验证码图片">欢迎使用 </body> </html> |
||
========== * * * * * ==========
|
返回 |