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);
} }
13.MD5对用户密码进行加密的更多相关文章
- C#:使用MD5对用户密码加密与解密
		C#中常涉及到对用户密码的加密于解密的算法,其中使用MD5加密是最常见的的实现方式.本文总结了通用的算法并结合了自己的一点小经验,分享给大家. 一.使用16位.32位.64位MD5方法对用户名加密 1 ... 
- 转   C#:使用MD5对用户密码加密与解密
		C#中常涉及到对用户密码的加密于解密的算法,其中使用MD5加密是最常见的的实现方式.本文总结了通用的算法并结合了自己的一点小经验,分享给大家. 一.使用16位.32位.64位MD5方法对用户名加密 1 ... 
- node.js中用户密码的加密
		crypro实现用户密码的加密 在实际的项目中,只要涉及到用户的信息,就是十分重要的.设想一下数据库里面存放的用户的密码是明文的形式,后果是有多严重.所以今天给大家分享一下express中怎样实现用户 ... 
- 如何正确对用户密码进行加密?转自https://blog.csdn.net/zhouyan8603/article/details/80473083
		本文介绍了对密码哈希加密的基础知识,以及什么是正确的加密方式.还介绍了常见的密码破解方法,给出了如何避免密码被破解的思路.相信读者阅读本文后,就会对密码的加密有一个正确的认识,并对密码正确进行加密措施 ... 
- django删除表重建&修改用户密码&base64加密解密字符串&ps aux参数说明&各种Error例子
		1.django的queryset不支持负索引 AssertionError: Negative indexing is not supported. 2.django向前端JavaScript传递列 ... 
- MySQL数据库(13)----忘记root用户密码解决方案【转载】
		1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态下,其他的用户也可以任意地登录 ... 
- 使用 spring security 中的BcryptPasswordEncoder对象对用户密码进行加密
		一.引入security启动器 在子工程中直接引入,不用指定版本号 二.在启动类中把BCryptPasswordEncoder对象注入到容器中 三.在service 层注入 四. 调用encode方法 ... 
- Linux用户密码策略
		使用Linux快三年了,从未想过Linux用户密码策略,从未把一本Linux的书从头看到尾(上学时的教材除外),故不知书上有无介绍,直到最近参加公司的信息安全稽核会议后才开始考虑Linux用户密码策略 ... 
- c# 对用户密码加密解密
		一.使用16位.32位.64位MD5方法对用户名加密 1)16位的MD5加密 ? 1 2 3 4 5 6 7 8 9 10 11 12 /// <summary> /// 16位MD5加密 ... 
随机推荐
- Windows 7 英文版操作系统中文软件乱码解决方法
			http://blog.csdn.net/lqhbupt/article/details/18863243 
- Solr增删改查索引
			一.添加索引,提交文档 1.如图,我的xml文档有predicate.object字段,这些在Solr配置文档里没有,所以xml文档提交不了 2.在F:\solr-4.10.0\example\sol ... 
- RESTful API 学习
			/********************************************************************************* * RESTful API 学习 ... 
- SendTo MD5 - imsoft.cnblogs
			SendTo MD5 is a small application that allows you to calculate and compare MD5 checksums of files an ... 
- dfs 与 剪枝
			http://blog.csdn.net/u010700335/article/details/44095171 
- 《DSP using MATLAB》Problem 3.9
			利用的频移性质为: 本习题代码: %% ------------------------------------------------------------------------ %% Outp ... 
- 前端内容安全策略(csp)
			什么是CSP CSP全称Content Security Policy ,可以直接翻译为内容安全策略,说白了,就是为了页面内容安全而制定的一系列防护策略. 通过CSP所约束的的规责指定可信的内容来源( ... 
- HDU1423 Greatest Common Increasing Subsequence
			题意 如标题. \(|s1|,|s2| \leq 500\) 分析 既然是dp问题的组合,那么考虑dp. 定义状态f(i,j)表示对第一个序列s1的前i个和第二个序列s2的前j个元素求最长上升公共子序 ... 
- SolrCloud6.3 单机、集群、内置jetty、tomcat搭建、对collection操作
			参考:https://my.oschina.net/u/1416405/blog/821187 1.Solr 单机 1.1.Solr下载 1.solr官网:http://lucene.apache.o ... 
- android 发送UDP广播,搜寻server建立socket链接
			应用场景:client(手机.pc)须要搜寻所在局域网内的server并获得server地址. 方法简单介绍:client发送UDP广播,服务收到广播后得到clientip地址,然后向client发送 ... 
