加密方式介绍
- 对称加密:加密和解密使用的相同的密钥,常见的对称加密算法有:DES、3DES
- 非对称加密:加密和解密使用的密钥不同,常见的非对称加密算法有:RSA
- 消息摘要: 消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密,只有相同的原文经过消息摘要算法之后,才能得到相同的密文,所以消息摘要通常用来校验原文的真伪。常用的消息摘要算法有:MD5、SHA、MAC
- MD5加密
MD5加密是一种常见的加密方式,我们经常用在保存用户密码和关键信息上。
MD5加密特点:
- 针对不同长度待加密的数据、字符串等等,其都可以返回一个固定长度的MD5加密字符串。(通常32位的16进制字符串);
- 加密过程几乎不可逆,除非用一个庞大的Key-Value数据库来进行碰撞破解,否则几乎无法解开。
- 运算简便,且可实现方式多样,通过一定的处理方式也可以避免碰撞算法的破解。
对于一个固定的字符串。数字等等,MD5加密后的字符串是固定的,也就是说不管MD5加密多少次,都是同样的结果。
1 使用JDK自带的API实现MD5util工具类进行加密
封装执行加密的工具类(MD5Util.java)可以直接在addUSer()方法运行前进行加密
| public class MD5Util { |
| |
| |
| |
| |
| |
| |
| public static String encode(String source) { |
| |
| |
| if (source == null || "".equals(source)) { |
| throw new RuntimeException("用于加密的明文不可为空"); |
| } |
| |
| |
| String algorithm = "md5"; |
| |
| |
| MessageDigest messageDigest = null; |
| try { |
| messageDigest = MessageDigest.getInstance(algorithm); |
| } catch (NoSuchAlgorithmException e) { |
| e.printStackTrace(); |
| } |
| |
| |
| byte[] input = source.getBytes(); |
| |
| |
| byte[] output = messageDigest.digest(input); |
| |
| |
| int signum = 1; |
| BigInteger bigInteger = new BigInteger(signum, output); |
| |
| |
| int radix = 16; |
| String encoded = bigInteger.toString(radix).toUpperCase(); |
| |
| return encoded; |
| } |
| } |
2. 使用Spring的DigestUtils工具类
测试代码如下:
| void testMD5() { |
| String pwd = "123456"; |
| |
| String hashedPwd1 = DigestUtils.md5DigestAsHex((pwd).getBytes()); |
| System.out.println(hashedPwd1); |
| } |
怕不够安全可以进行“加盐”
处理:
| void testMD5() { |
| String pwd = "123456"; |
| String salt = UUID.randomUUID().toString(); |
| |
| String hashedPwd1 = DigestUtils.md5DigestAsHex((pwd + salt).getBytes()); |
| System.out.println(hashedPwd1); |
| } |
也可以进行多次加盐
| void testMD5() { |
| String pwd = "123456"; |
| String salt = UUID.randomUUID().toString(); |
| |
| String hashedPwd1 = DigestUtils.md5DigestAsHex((pwd + salt).getBytes()); |
| hashedPwd1 = DigestUtils.md5DigestAsHex((hashedPwd1 + salt).getBytes()); |
| hashedPwd1 = DigestUtils.md5DigestAsHex((hashedPwd1 + salt).getBytes()); |
| |
| System.out.println(hashedPwd1); |
| } |
3创建连接数据库的工具类
| package com.example.util; |
| |
| import com.alibaba.druid.pool.DruidDataSourceFactory; |
| |
| import javax.sql.DataSource; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.sql.Connection; |
| import java.util.Properties; |
| |
| public class JDBCUtils { |
| private static DataSource dataSource =null; |
| private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>(); |
| |
| static{ |
| |
| Properties prop = new Properties(); |
| |
| InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties"); |
| try { |
| prop.load(is); |
| |
| |
| dataSource = DruidDataSourceFactory.createDataSource(prop); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| |
| public static Connection getConnection(){ |
| |
| Connection conn = threadLocal.get(); |
| |
| if(conn ==null ){ |
| try { |
| |
| conn = dataSource.getConnection(); |
| |
| threadLocal.set(conn); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| return conn; |
| } |
| |
| public static void releaseConnection(){ |
| |
| Connection conn = threadLocal.get(); |
| try { |
| if(conn !=null){ |
| conn.close(); |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| }finally { |
| |
| |
| threadLocal.remove(); |
| } |
| } |
| } |
| |
4创建BaseDao
| package com.example.dao; |
| |
| import com.example.util.JDBCUtils; |
| import org.apache.commons.dbutils.QueryRunner; |
| import org.apache.commons.dbutils.handlers.BeanHandler; |
| import org.apache.commons.dbutils.handlers.BeanListHandler; |
| import org.apache.commons.dbutils.handlers.ScalarHandler; |
| |
| import java.sql.Connection; |
| import java.sql.SQLException; |
| import java.util.List; |
| |
| |
| |
| |
| |
| |
| public class BaseDao<T> { |
| |
| private QueryRunner runner=new QueryRunner(); |
| |
| |
| |
| |
| |
| |
| public boolean update(String sql,Object...params){ |
| |
| Connection connection = JDBCUtils.getConnection(); |
| |
| try { |
| int update = runner.update(connection, sql, params); |
| if(update>0) |
| return true; |
| } catch (SQLException e) { |
| e.printStackTrace(); |
| }finally { |
| |
| JDBCUtils.releaseConnection(); |
| } |
| return false; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| public List<T> getBeanList(Class type,String sql,Object...params){ |
| |
| Connection connection = JDBCUtils.getConnection(); |
| |
| try { |
| return runner.query(connection, sql, new BeanListHandler<T>(type), params); |
| } catch (SQLException e) { |
| e.printStackTrace(); |
| }finally{ |
| |
| JDBCUtils.releaseConnection(); |
| } |
| return null; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| public T getBean(Class type,String sql,Object...params){ |
| |
| Connection connection = JDBCUtils.getConnection(); |
| |
| try { |
| return runner.query(connection,sql,new BeanHandler<T>(type),params); |
| } catch (SQLException e) { |
| e.printStackTrace(); |
| }finally{ |
| |
| JDBCUtils.releaseConnection(); |
| } |
| return null; |
| } |
| |
| |
| |
| |
| |
| |
| |
| public Object getObject(String sql,Object...params){ |
| |
| Connection connection = JDBCUtils.getConnection(); |
| |
| try { |
| return runner.query(connection,sql,new ScalarHandler(),params); |
| } catch (SQLException e) { |
| e.printStackTrace(); |
| }finally{ |
| |
| JDBCUtils.releaseConnection(); |
| } |
| return null; |
| } |
| } |
5创建注册RegistServlet.java
| package com.example.servlet; |
| |
| import com.example.bean.User; |
| import com.example.dao.UserDao; |
| import com.example.dao.impl.UserDaoImpl; |
| import com.example.util.MD5Util; |
| import org.apache.commons.beanutils.BeanUtils; |
| |
| import javax.servlet.*; |
| import javax.servlet.http.*; |
| import javax.servlet.annotation.*; |
| import java.io.IOException; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.Map; |
| |
| @WebServlet(name = "RegistServlet", value = "/RegistServlet") |
| public class RegistServlet extends HttpServlet { |
| @Override |
| protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { |
| doPost(request,response); |
| } |
| |
| @Override |
| protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { |
| |
| Map<String, String[]> parameterMap = request.getParameterMap(); |
| User user=new User(); |
| try { |
| BeanUtils.populate(user,parameterMap); |
| } catch (IllegalAccessException e) { |
| throw new RuntimeException(e); |
| } catch (InvocationTargetException e) { |
| throw new RuntimeException(e); |
| } |
| |
| |
| UserDao userDao=new UserDaoImpl(); |
| System.out.println("密码设置为="+user.getPassword()); |
| String encode=MD5Util.encode(user.getPassword()); |
| user.setPassword(encode); |
| System.out.println("加密成功="+encode); |
| boolean b=userDao.addUser(user); |
| System.out.println("添加成功"); |
| |
| if (b){ |
| request.getRequestDispatcher("/pages/user/regist_success.html").forward(request,response); |
| |
| }else { |
| request.getRequestDispatcher("/pages/user/regist_error.html").forward(request,response); |
| } |
| } |
| } |
| |
前端表单
| <form action="RegistServlet" @submit="checkAll"> |
| <div class="form-item"> |
| <div> |
| <label>用户名称:</label> |
| <input type="text" placeholder="请输入用户名" name="username" @blur="checkUsername" v-model="username" /> |
| </div> |
| <span class="errMess">{{usernameErrMsg}}</span> |
| </div> |
| <div class="form-item"> |
| <div> |
| <label>用户密码:</label> |
| <input type="password" placeholder="请输入密码" name="password" @blur="checkPassword" v-model="password"/> |
| </div> |
| <span class="errMess">{{passwordErrMsg}}</span> |
| </div> |
| <div class="form-item"> |
| <div> |
| <label>确认密码:</label> |
| <input type="password" placeholder="请输入确认密码" @blur="checkConfirmPassword" v-model="confirmPassword"/> |
| </div> |
| <span class="errMess">{{confirmPasswordErrMsg}}</span> |
| </div> |
| <div class="form-item"> |
| <div> |
| <label>用户邮箱:</label> |
| <input type="text" placeholder="请输入邮箱"name="email" @blur="checkEmail" v-model="email"/> |
| </div> |
| <span class="errMess">{{emailErrMsg}}</span> |
| </div> |
| |
| <div class="form-item"> |
| <div> |
| <label>验证码:</label> |
| <div class="verify"> |
| <input type="text" placeholder="" /> |
| <img src="static/img/code.bmp" alt="" height="50px"/> |
| </div> |
| </div> |
| <span class="errMess">请输入正确的验证码</span> |
| </div> |
| <button class="btn">注册</button> |
| </form> |
测试

数据库表:

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?