【JavaEE进阶】数据库加密 -- MD5 加密方法

目录

1. 加密介绍

1.1 加密方法

 1.2 "盐值"(随机字符串的获取方法)

2. 编写加密/解密工具类


1. 加密介绍

在MySQL数据库中,我们常常需要对密码, 身份证号, 手机号等敏感信息进行加密, 以保证数据的安全性. 如果使用明文存储, 当黑客入侵了数据库时, 就可以轻松获取到用户的相关信息, 从而对用户或者企业造成信息泄漏或者财产损失.

目前我们用户的密码还是明文设置的,为了保护用户的密码信息,我们需要对密码进行加密
 

加密算法分类

密码算法主要分为三类: 对称密码算法, 非对称密码算法, 摘要算法

1. 对称密码算法 是指加密秘钥和解密秘钥相同的密码算法. 常见的对称密码算法有: AES, DES, 3DES,RC4, RC5, RC6等. 

2. 非对称密码算法 是指加密秘钥和解密秘钥不同的密码算法.该算法使用一一个秘钥进行加密,用另外一个秘钥进行解密.

  • 加密秘钥可以公开,又称为公钥
  • 解密秘钥必须保密,又称为私钥

常见的非对称密码算法有: RSA, DSA, ECDSA, ECC等

3. 摘要算法 是指把任意长度的输入消息数据转化为固定长度的输出数据的一种密码算法. 摘要算法是不可逆的, 也就是无法解密. 通常用来检验数据的完整性的重要技术, 即对数据进行哈希计算然后比较摘要值, 判断是否一致. 常见的摘要算法有: MD5, SHA系列(SHA1, SHA2等),  CRC(CRC8, CRC16, CRC32)
 

加密思路

在这篇文章中中,我们学习MD5算法加密的方式.

问题: 虽然经过MD5加密后的密文无法解密,但由于相同的密码经过 MD5 哈希之后的密文是相同的, 当存储用户密码的数据库泄露后,攻击者会很容易便能找到相同密码的用户,从而降低了破解密码的难度. 因此, 在对用户密码进行加密时,需要考虑对密码进行包装,即使是相同的密码,也保存为不同的密文. 即使用户输入的是弱密码, 也考虑进行增强,从而增加密码被攻破的难度.

解决方案: 采用为一个密码拼接一个随机字符来进行加密, 这个随机字符我们称之为 "盐". 假如有一个加盐后的加密串,黑客通过一定手段获得这个加密串,他拿到的明文并不是我们加密前的字符串, 而是加密前的字符串和盐组合的字符串,这样相对来说又增加了字符串的安全性.

解密流程: MD5是不可逆的, 通常采用 "判断哈希值是否一致" 来判断密码是否正确.

如果用户输入的密码,和盐值一起拼接后的字符串经过加密算法, 得到的密文相同,我们就认为密码正确.(密文相同, 盐值相同, 推测明文相同)

1.1 加密方法

在 Spring 框架中,org.springframework.util.DigestUtils类提供了一些方便的方法来进行常见的摘要(包括 MD5)计算。

DigestUtils类中的md5DigestAsHex方法用于计算输入数据的 MD5 摘要,并以十六进制字符串的形式返回。

使用示例:

import org.springframework.util.DigestUtils;

public class MD5Utils {
    public static void main(String[] args) {
        //对"123456"进行md5加密
        String key = DigestUtils.md5DigestAsHex("123456".getBytes());
        //输出加密后的字符串
        System.out.println(key);
    }
}

 1.2 "盐值"(随机字符串的获取方法)

在 Java 中,UUID(Universally Unique Identifier)是一种用于生成唯一标识符的类。

UUID 是一个 128 位的数字,通常以 36 个字符的字符串形式表示,格式为 8 - 4 - 4 - 4 - 12。它具有非常高的随机性和唯一性,几乎可以保证在不同的时间和空间生成的 UUID 不会重复。

Java 中可以通过java.util.UUID类来生成 UUID。例如:

public static void main(String[] args) {
        String s1 = UUID.randomUUID().toString();
        String s2 = UUID.randomUUID().toString();
        String s3 = UUID.randomUUID().toString();
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
}

 

2. 编写加密/解密工具类

我们在数据库存放密码时, 需要将盐值和密码存储在一起, 为了不轻易被破解, 盐值和密码可以以某种形式进行分割和拼接 (在校验密码的时候需要能够把盐值以同样的方式完整的取出来)

在这里, 我们以 盐值 + md5(明文+盐值) 的形式存储, 当然推荐其他复杂的组合形式.

import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.UUID;

public class SecurityUtils {
    /**
     * 加密
     * inputPassword: 用户注册时输入的密码
     * return: 数据库中存储的信息: 盐值+md5(明文+盐值)
     */
    public static String encrypt(String password) {
        //生成随机盐值
        String salt = UUID.randomUUID().toString().replace("-","");
        //对 明文+盐值 进行md5加密
        String finalPassword = DigestUtils.md5DigestAsHex((password + salt).getBytes());
        return salt + finalPassword;
    }

    /**
     * 验证密码是否正确
     * @param inputPassword 用户登录时输入的密码
     * @param sqlPassword 数据库中password字段存储的信息 盐值+md5(明文+盐值)
     * @return
     */
    public static boolean verify(String inputPassword , String sqlPassword) {
        if(!StringUtils.hasLength(inputPassword) || !StringUtils.hasLength(sqlPassword) || sqlPassword.length()!=64) {
            return false;
        }
        //获取盐值
        String salt = sqlPassword.substring(0, 32);
        //根据用户登录输入的密码和盐值进行加密 md5(明文+盐值)
        String finalPassword = DigestUtils.md5DigestAsHex((inputPassword+salt).getBytes());

        return (salt+finalPassword).equals(sqlPassword);
    }
}

在用户注册时, 使用 encrypt 方法进行加密:

用户登录时, 使用 verify 方法来校验密码是否正确:

以上就是这篇文章的主要内容了.

 

  • 26
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏微凉.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值