zoukankan      html  css  js  c++  java
  • 13.MD5对用户密码进行加密

    MD5概述

    用户名密码保存在客户端是一种十分危险的行为。所以需要进行加密后保存。

    其中MD5就是一种比较常用的加密算法。

    与其说MD5算法是一种加密算法,不如说是一种数据指纹(数据摘要)算法。

    其特点如下:

    任意大小的二进制数经过MD5计算后都能得到一个独一无二的128位二进制数。

    不同的数据算出的MD5绝对不相同。

    相同的数据算出的MD5一定相同。

    只能有明文算出密文,密文是永远也无法算成明文的。

    MD5大量应用于计算机中。如数据库中保存的密码通常都是经过MD5加密后的数据。如用户下载文件时可以进行MD5校验防止数据被篡改。

    在记住用户名案例中,我们可以使用MD5进行加密后再保存在客户端,从而保证数据安全。

    在数据库中保存的密码也不宜直接存储为明文。也要经过MD5加密后存储。

    第一步:编写一个MD5的工具类

    package cn.bingou.util;
    
    import java.math.BigInteger;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    public class MD5Utils {
        
        public static String md5(String plainText){
            // 用来保存加密后的密文的数组
            byte[] secreBytes = null;
            
            try {
                // 将明文转成byte数组并进行加密,获得密文数组
                secreBytes = MessageDigest.getInstance("md5").digest(
                        plainText.getBytes());
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException("没有md5这个算法");
            }
            // 将二进制数组转车过16进制表示的字符串
            String md5code = new BigInteger(1, secreBytes).toString(16);
            //128位2进制数组转成16进制时,可能不足32位
            //在字符串前面补0,使所有的字符串长度一定是32位
            for(int i=0; i<32-md5code.length();i++){
                md5code = "0"+md5code;
            }
            return md5code;
        }
    }

    第二步:调用工具类

    注册用户的代码中调用MD5的工具类,将明文密码变为MD5密文。

    package cn.bingou.web;
    
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import cn.bingou.domain.User;
    import cn.bingou.factory.BaseFactory;
    import cn.bingou.service.UserService;
    import cn.bingou.service.UserServiceImpl;
    import cn.bingou.util.JDBCUtils;
    import cn.bingou.util.MD5Utils;
    import cn.bingou.util.WebUtils;
    
    public class RegistServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
    
    //        // 1.请求乱码问题
    //            // 请求乱码-POST请求
    //        req.setCharacterEncoding("utf-8");
    //            // 应答乱码问题
    //        resp.setContentType("text/html;charset=utf-8");
            
            // 2.接收表单参数
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            String password2 = req.getParameter("password2");
            String nickname = req.getParameter("nickname");
            String email = req.getParameter("email");
            String valistr = req.getParameter("valistr");
            
            // 3.验证表单
                // 1)非空验证
                
            if(WebUtils.isEmpty(username)){ // 用户名为空验证
                // 向request作用域中添加错误提示信息
                req.setAttribute("errMsg", "用户名不能为空!");
                // 将请求转发给regist.jsp,forward():请求转发
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                // 如果用户输入为空,直接返回
                return;
            }
            if(WebUtils.isEmpty(password)){ // 密码为空验证
                req.setAttribute("errMsg", "密码不能为空!");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
            if(WebUtils.isEmpty(nickname)){ // 昵称为空验证
                req.setAttribute("errMsg", "昵称不能为空!");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
            if(WebUtils.isEmpty(email)){ // 邮箱为空验证
                req.setAttribute("errMsg", "邮箱不能为空!");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
            
                // 2)密码一致验证
            if(!password.equals(password2)){
                // 如果密码与确认密码不一样,则输出错误
                req.setAttribute("errMsg", "密码不一致");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
            
                // 3)邮箱格式验证
                // abc@123.163.com
            String reg="^\w+@\w+(\.\w+)+$"; 
            if(!email.matches(reg)){
                req.setAttribute("errMsg", "邮箱格式不符");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
                    
                // 4)用户名是否存在
            UserService userService=BaseFactory.getFactory().getInstance(UserService.class);
            boolean flag=userService.hasUsername(username);
            if(flag){//用户名已存在
                // 向request作用域中添加错误提示信息
                req.setAttribute("errMsg", "用户名已存在");
                // 将请求转发给regist.jsp
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
            
                // 5)验证码验证
            if(WebUtils.isEmpty(valistr)){ // 验证码为空验证
                req.setAttribute("errMsg", "验证码不能为空!");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            } else{
                // 验证码不为空,执行验证码内容验证
                // 获取保存在session中的正确验证码
                HttpSession session=req.getSession(false);// 如果当前Session没有就为null
                boolean flag1=true; // 默认验证码没有问题
                if(session==null && session.getAttribute("text")==null){
                    // 没有session对象,或者session中没有正确的验证码文本
                    flag1=false;
                }else{
                    String text=(String) session.getAttribute("text");
                    if(!valistr.equalsIgnoreCase(text)){
                        // 用户输入的文本和正确文本不一致
                        flag1=false;
                    }
                }
                if(flag1==false){
                    // 向request作用域中添加错误提示信息
                    req.setAttribute("errMsg", "验证码错误");
                    // 将请求转发给regist.jsp
                    req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                    return;
                }
            }
            
            // 将密码进行MD5加密
            password=MD5Utils.md5(password);
            // 4.数据存入数据库
            User user=new User(-1, username, password, nickname, email);
            
            boolean flag1=userService.registUser(user);
            if(flag1){// 保存成功-提示成功信息,定时刷新到首页
                resp.getWriter().write("<h1 style='text-align:center;color:red'>恭喜您,注册成功!3秒后自动跳转首页</h1>");
                // 实现定时刷新
                resp.setHeader("refresh", "3;url="+req.getContextPath()+"/index.jsp");
            }else{
                req.setAttribute("errMsg", "注册出现异常,请稍后重试...");
                req.getRequestDispatcher("/regist.jsp").forward(req, resp);
                return;
            }
        }
    
        public void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            doGet(req, resp);
        }
    
    }

    用户登陆的时候也要将输入的密码转换成MD5加密之后的密文,与数据库里面的密文进行比对。

    package cn.bingou.web;
    
    import java.io.IOException;
    import java.net.URLEncoder;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import cn.bingou.domain.User;
    import cn.bingou.exception.MsgException;
    import cn.bingou.factory.BaseFactory;
    import cn.bingou.service.UserService;
    import cn.bingou.util.MD5Utils;
    
    public class LoginServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
    
            // 获取web.xml中配置的字符集
            String encode=this.getServletContext().getInitParameter("encode");
    //        // 1.处理乱码-请求乱码
    //        // POST请求乱码
    //        req.setCharacterEncoding(encode);
            // 2.接收请求参数
            String username=req.getParameter("username");// 使用request.getParameter可以获得表单传过来的值 
            String password=req.getParameter("password");
            String remname=req.getParameter("remname");
            // 3.表单验证
            // 将用户的明文密码转成MD5加密后的密码
            password=MD5Utils.md5(password);
            // 4.执行逻辑 
                // 1)记住用户名
                // 判断用户是否勾选了记住用户名
            if(remname != null && "true".equals(remname)){
                // 勾选了记住用户名
                // 创建一个保存用户名的Cookie
                // URLEncoder.encode用来对一个字符串进行编码
                Cookie cookie=new Cookie("rename",URLEncoder.encode(username,encode));
                // 设置一个有效时间
                cookie.setMaxAge(60*60*24*30);
                // 手动设置一个路径 web应用的根路径
                // EasyMall被配置成了虚拟主机的默认web应用
                // 导致req.getContextPath()返回 ""
                // setPath("")-》无效的,所以setPath(""+"/")->有效            
                cookie.setPath(req.getContextPath()+"/");
                // 将Cookie添加到Response中
                resp.addCookie(cookie);
            }else{
                // 如果没有勾选记住用户名-删除之前保存的Cookie
                Cookie cookie=new Cookie("remname","");
                cookie.setPath(req.getContextPath()+"/");
                cookie.setMaxAge(0);// 删除当前Cookie
                resp.addCookie(cookie);
            }
                // 2)登陆
                // 判断用户的用户名和密码是否正确
            UserService userServlet=BaseFactory.getFactory().getInstance(UserService.class);
            
            User user=null;
            try {
                user=userServlet.login(username, password);
            } catch (MsgException e) {
                e.printStackTrace();
                req.setAttribute("errMsg", e.getMessage());
                req.getRequestDispatcher("/login.jsp").forward(req, resp);
                return;
            }
            
            if(user != null){
                // 登录成功-向session中添加登录状态
                req.getSession().setAttribute("user", username);
                System.out.println(user.getUsername());
                System.out.println(username);
                // 重定向到首页
                resp.sendRedirect(req.getContextPath()+"/index.jsp");
            }else{
                //添加错误提示信息,并返回login.jsp
                req.setAttribute("errMsg", "用户名或密码错误");
                req.getRequestDispatcher("/login.jsp").forward(req, resp);
            }
        }
    
        public void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            doGet(req, resp);
        }
    
    }
  • 相关阅读:
    使用jQuery实现伪分页
    使用jQuery实现option的上移和下移
    理解Flux架构
    React 入门学习笔记1
    ES6新特性6:模块Module
    ES6新特性5:类(Class)和继承(Extends)
    ES6新特性4:字符串的扩展
    ES6新特性3:函数的扩展
    ES6新特性2:变量的解构赋值
    ES6新特性1:let和const
  • 原文地址:https://www.cnblogs.com/chuijingjing/p/9813870.html
Copyright © 2011-2022 走看看