java开发-用户注册-MD5工具加密密码

news2025/3/14 20:08:49

加密方式介绍

  • 对称加密:加密和解密使用的相同的密钥,常见的对称加密算法有:DES、3DES
  • 非对称加密:加密和解密使用的密钥不同,常见的非对称加密算法有:RSA
    • 加密:使用私钥加密
    • 解密:使用公钥解密
  • 消息摘要: 消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密,只有相同的原文经过消息摘要算法之后,才能得到相同的密文,所以消息摘要通常用来校验原文的真伪。常用的消息摘要算法有:MD5、SHA、MAC

- MD5加密

MD5加密是一种常见的加密方式,我们经常用在保存用户密码和关键信息上。
MD5加密特点:

  1. 针对不同长度待加密的数据、字符串等等,其都可以返回一个固定长度的MD5加密字符串。(通常32位的16进制字符串);
  2. 加密过程几乎不可逆,除非用一个庞大的Key-Value数据库来进行碰撞破解,否则几乎无法解开。
  3. 运算简便,且可实现方式多样,通过一定的处理方式也可以避免碰撞算法的破解。
    对于一个固定的字符串。数字等等,MD5加密后的字符串是固定的,也就是说不管MD5加密多少次,都是同样的结果。
1 使用JDK自带的API实现MD5util工具类进行加密

封装执行加密的工具类(MD5Util.java)可以直接在addUSer()方法运行前进行加密

public class MD5Util {

    /**
     * 针对明文字符串执行MD5加密
     * @param source
     * @return
     */
    public static String encode(String source) {

        // 1.判断明文字符串是否有效
        if (source == null || "".equals(source)) {
            throw new RuntimeException("用于加密的明文不可为空");
        }

        // 2.声明算法名称
        String algorithm = "md5";

        // 3.获取MessageDigest对象
        MessageDigest messageDigest = null;
        try {
            messageDigest = MessageDigest.getInstance(algorithm);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        // 4.获取明文字符串对应的字节数组
        byte[] input = source.getBytes();

        // 5.执行加密
        byte[] output = messageDigest.digest(input);

        // 6.创建BigInteger对象
        int signum = 1;
        BigInteger bigInteger = new BigInteger(signum, output);

        // 7.按照16进制将bigInteger的值转换为字符串
        int radix = 16;
        String encoded = bigInteger.toString(radix).toUpperCase();

        return encoded;
    }
}

2. 使用Spring的DigestUtils工具类

测试代码如下:

void testMD5() {
    String pwd = "123456";
    // 基于spring框架中的DigestUtils工具类进行密码加密
    String hashedPwd1 = DigestUtils.md5DigestAsHex((pwd).getBytes());
    System.out.println(hashedPwd1); 
}

怕不够安全可以进行“加盐”处理:

void testMD5() {
    String pwd = "123456";
    String salt = UUID.randomUUID().toString();
    // 基于spring框架中的DigestUtils工具类进行密码加密
    String hashedPwd1 = DigestUtils.md5DigestAsHex((pwd + salt).getBytes());
    System.out.println(hashedPwd1);
}

也可以进行多次加盐

void testMD5() {
    String pwd = "123456";
    String salt = UUID.randomUUID().toString();
    // 基于spring框架中的DigestUtils工具类进行密码加密
    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();
        //System.out.println("prop1:"+prop);
        InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            prop.load(is);
            //System.out.println("prop2:"+prop);
            //根据属性文件创建连接池
            dataSource = DruidDataSourceFactory.createDataSource(prop);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取数据库连接
    public static Connection getConnection(){
        //先从ThreadLocal中获取
        Connection conn = threadLocal.get();
        //如果没有连接,说明是该线程中第一次访问,
        if(conn ==null ){
            try {
                //从连接池中获取一个连接
                conn = dataSource.getConnection();
                //放入到threadLocal中
                threadLocal.set(conn);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //返回连接
        return conn;
    }
    //关闭数据库连接(如果采用了连接池,就是归还连接)
    public static void releaseConnection(){
        //从threadLocal中获取
        Connection conn = threadLocal.get();
        try {
            if(conn !=null){
                conn.close(); //不是物理关闭,而是放入到连接池中,置为空闲状态
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //这个语句不要少
            //threadLocal.set(null);//连接已经放回连接池,不使用了。ThreadLocal也不需要再保存了
            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> {
    //2. 创建QueryRunner对象
    private QueryRunner runner=new QueryRunner();
    /**
     * 功能:对数据库进行增删改的操作
     * @param sql
     * @param params
     * @return
     */
    public boolean update(String sql,Object...params){
        //1. 获得数据库连接
        Connection connection = JDBCUtils.getConnection();
        //3. 执行
        try {
            int update = runner.update(connection, sql, params);
            if(update>0)
                return true;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //4. 释放资源
            JDBCUtils.releaseConnection();
        }
        return false;
    }

    /**
     * 功能:查询多条数据
     * @param type
     * @param sql
     * @param params
     * @return
     */
    public List<T> getBeanList(Class type,String sql,Object...params){
        //1. 获得数据库连接
        Connection connection = JDBCUtils.getConnection();
        //3. 执行
        try {
            return runner.query(connection, sql, new BeanListHandler<T>(type), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            //4. 释放资源
            JDBCUtils.releaseConnection();
        }
        return null;
    }

    /**
     * 功能:查询一条结果
     * @param type
     * @param sql
     * @param params
     * @return
     */
    public T getBean(Class type,String sql,Object...params){
        //1. 获得数据库连接
        Connection connection = JDBCUtils.getConnection();
        //3. 执行
        try {
            return runner.query(connection,sql,new BeanHandler<T>(type),params);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            //4. 释放资源
            JDBCUtils.releaseConnection();
        }
        return null;
    }

    /**
     * 功能:查询一个结果
     * @param sql
     * @param params
     * @return
     */
    public Object getObject(String sql,Object...params){
        //1. 获得数据库连接
        Connection connection = JDBCUtils.getConnection();
        //3. 执行
        try {
            return runner.query(connection,sql,new ScalarHandler(),params);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            //4. 释放资源
            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 {
        //1获得请求参数
        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);
        }
        //2 处理注册业务
        //将信息添加到数据库,需要考虑密码加密问题。
        UserDao userDao=new UserDaoImpl();
        System.out.println("密码设置为="+user.getPassword());
        String encode=MD5Util.encode(user.getPassword());//encode是加密后的密码
        user.setPassword(encode);
        System.out.println("加密成功="+encode);
        boolean b=userDao.addUser(user);
        System.out.println("添加成功");
        //3 响应(页面跳转)
        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>
测试

在这里插入图片描述
数据库表:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/335019.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vcs仿真教程

VCS是在linux下面用来进行仿真看波形的工具&#xff0c;类似于windows下面的modelsim以及questasim等工具&#xff0c;以及quartus、vivado仿真的操作。 1.vcs的基本指令 vcs的常见指令后缀 sim常见指令 2.使用vcs的实例 采用的是全加器的官方教程&#xff0c;首先介绍不使用…

Netty(IO模型/零拷贝技术/IO复用之select、poll、epoll模型)

目录 IO模型 阻塞IO和非阻塞IO 阻塞IO 非阻塞IO IO复用模型 异步IO mmap IO复用之select、poll、epoll模型 select poll epoll IO模型 阻塞IO和非阻塞IO 阻塞IO 所谓阻塞IO就是当应用B发起读取数据申请时&#xff0c;在内核数据没有准备好之前&#xff0c;应用…

分享111个JS菜单导航,总有一款适合您

分享111个JS菜单导航&#xff0c;总有一款适合您 111个JS菜单导航下载链接&#xff1a;https://pan.baidu.com/s/1WkrSIyHC5JySwrCTL0sgLA?pwd13yx 提取码&#xff1a;13yx Python采集代码下载链接&#xff1a;https://wwgn.lanzoul.com/iKGwb0kye3wj base_url "h…

【GPLT 二阶题目集】L2-036 网红点打卡攻略

一个旅游景点&#xff0c;如果被带火了的话&#xff0c;就被称为“网红点”。大家来网红点游玩&#xff0c;俗称“打卡”。在各个网红点打卡的快&#xff08;省&#xff09;乐&#xff08;钱&#xff09;方法称为“攻略”。你的任务就是从一大堆攻略中&#xff0c;找出那个能在…

开源ChatGPT要来了;软件2.0智能革命;GLM、Diffusion模型大加速

1. 2023年AI十大展望&#xff1a;GPT-4领衔大模型变革&#xff0c;谷歌拉响警报&#xff0c;训练数据告急 新年伊始&#xff0c;大模型的话题热度不减。ChatGPT展现的惊人能力将大模型研究和应用热度推向高潮&#xff0c;人们激烈讨论着这个高级“物种”的推出意味着什么。 本文…

如何操作python的列表和元组?

继上篇文章&#xff0c;我们叙述了 列表是什么&#xff1f; 这篇文章&#xff0c;我们主要叙述 列表如何操作。 如何遍历列表呢&#xff1f;这只需要几行代码&#xff0c;无论列表有多长。 循环让我们能够对列表的每个元素都采取一个或一系列相同的措施&#xff0c; 从而高效地…

CHAPTER 4 Jenkins pipeline (流水线)

Jenkins pipeline4.1 pipeline概念4.2 pipeline优势4.3 pipeline演示1. 新建任务2. 配置任务3. 执行任务4.4 pipeline语法4.4.1 片段生成器1. 生成git clone代码2. 执行任务4.4.2 pipeline语法详解1. 声明式流水线基础2. 脚本化流水线基础3. agent 执行位置4. tool 工具5. envi…

原生微信小程序按需引入vant

vant Vant Weapp - 轻量、可靠的小程序 UI 组件库 1.npm安装 找到项目根目录 安装 # 通过 npm 安装 npm i vant/weapp -S --production# 通过 yarn 安装 yarn add vant/weapp --production# 安装 0.x 版本 npm i vant-weapp -S --production 2 .修改 app.json 将 app.jso…

【GD32F427开发板试用】使用Arm-2D显示电池电量

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动&#xff0c;更多开发板试用活动请关注极术社区网站。作者&#xff1a;boc 【虽迟但到】 由于快递的原因&#xff0c;11月份申请的&#xff0c;12月1日才收到GD32F427开发板。虽然姗姗来迟&#xff0c;但也没有减少…

易记笔记-Ubuntu升级软件包及注意事项

APT介绍 APT是一个命令行实用程序&#xff0c;用于在Ubuntu系统中安装、删除、更新软件包。 注意&#xff0c;Ubuntu里面的APT工具需要与常说的APT攻击区分开。 APT攻击&#xff0c;即高级可持续威胁攻击,也称为定向威胁攻击&#xff0c;指某组织对特定对象展开的持续有效的攻…

CSDN每日一练:寻因找祖

题目名称&#xff1a;寻因找祖 时间限制&#xff1a;1000ms内存限制&#xff1a;256M 题目描述 寻找因子个数为n的最小整数x. 输入描述&#xff1a; 输入整数n。(1<n<1000) 输出描述&#xff1a; 输出x。 示例 示例1 输入 3 输出 4 提示 无 猛一看&#xff0c;这个题目很…

Node学习1

Node 加载模块&#xff1a; 加载内置模块和第三方模块直接require&#xff08;名字&#xff09; 自定义模块需要加路径 require&#xff08;&#xff09;加载模块时候会自动调用被加载模块代码require永远以module.export所指向的对象为准 模块作用域&#xff1a; 和函数作用…

QT之事件系统

QT之事件系统1. 概述2. 事件的传递3. 事件类型4. 事件处理与事件过滤5. 自定义事件5.1 Demo6. 发送事件7. 参考1. 概述 在QT中&#xff0c;事件均派生自QEvent抽象类&#xff0c;事件可以由任何派生自QObject的子类实例接收和处理。它们与widget关联性极强。 2. 事件的传递 …

有了这 4 款工具,老大再也不怕我写烂SQL了

一、mysqltuner.pl 是 MySQL 一个常用的数据库性能诊断工具&#xff0c;主要检查参数设置的合理性包括日志文件、存储引擎、安全建议及性能分析。针对潜在的问题&#xff0c;给出改进的建议。是 MySQL 优化的好帮手。 在上一版本中&#xff0c;MySQLTuner支持 MySQL / MariaD…

LightningChart JS v4.0.0 and LightningChart NET

LightningChart JS v4.0.0 引入了新的 DataGrid 组件、全面的折线图类型和视觉主题。2023 年 2 月 9 日 - 16:05 新版本特征 下一代色彩主题&#xff1a; 暗金。网络空间。绿松石六角形。光。光自然。自定义 - 创建您自己的下一代颜色主题。新的 DataGrid 组件 DataGrid 组件是…

linux基本功系列之tar命令实战

文章目录前言一. tar命令介绍二. 语法格式及常用选项三. 参考案例3.1 仅打包不压缩3.2 打包后使用调用压缩命令进行压缩3.3 列出文件的内容3.4 追加文件到tar命令中3.5 释放文件到指定的目录四 . 各种压缩方式的比较总结前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓…

开学季该准备哪款电容笔?2023平替电容笔推荐

如今&#xff0c;电容笔越来越受欢迎&#xff0c;性能也越来越好。所以&#xff0c;如何选择一款具有高性价比的电容笔就成了人们的重点关注。现在&#xff0c;越来越多的人开始使用电容笔&#xff0c;所以&#xff0c;人们都在寻求更好、更经济的电容笔。所以&#xff0c;什么…

21省人均GDP超过1万美元,北京以19.01万元继续稳居榜首

在过去的2022年&#xff0c;各省都交了优秀的“成绩单”&#xff0c;各省的经济强弱即将揭晓。广东与江苏的GDP均超过12万亿元&#xff0c;是31省中超过12万亿元的两个城市&#xff0c;GDP分别为12.91万亿元与12&#xff0c;18万亿元。山东省、浙江省、河南省紧随其后&#xff…

linux yum安装卸载jdk8

1>安装1 yum -y list java* 列出jdk列表2 yum install -y java-1.8.0-openjdk-demo.x86_64&#xff08;安装这个java -version 正常显示&#xff0c;但是javac不能用&#xff0c;因为yum install java 只是安装了java的运行时环境&#xff0c;并不支持编译&#xff0c;安装成…

如何在线批量压缩PDF

PDF格式文档是我们日常比较常用的格式文档之一&#xff0c;那么有什么方法可以减小PDF大小呢&#xff1f;如果PDF比较多是否能批量处理呢&#xff1f; 首先打开浏览器搜索speedpdf就能找到这个在线压缩工具&#xff0c;点击进入后选择PDF压缩可以。如果需要手机和电脑端同步压…