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)邮箱格式验证
            // [email protected]
        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);
    }

}

猜你喜欢

转载自www.cnblogs.com/chuijingjing/p/9813870.html