Java实现加盐加密算法的示例详解

 更新时间:2023年06月01日 08:45:05   作者:X_H学Java  
这篇文章主要为大家详细介绍了如何利用Java语言实现加盐加密算法,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下

为什么需要加密

从下面的图片中,可以看到用户的密码在数据库中存储时,如果不对密码加密,则是以明文的方式存储的,如果被别人获取到数据库的信息,那将会将用户的密码泄露,从而造成安全隐患

我们可以使用MD5加密方式对用户的密码进行加密存储,但是传统的MD5有规则可循,可以破解

String s = "12345";
String mds1 = DigestUtils.md5DigestAsHex(s.getBytes()).toString();
System.out.println(mds1);
String mds2 = DigestUtils.md5DigestAsHex(s.getBytes()).toString();
System.out.println(mds2);

我们从上述代码及打印结果看,使用MD5对同一个字符串加密,加密后的结果不变,MD5加密是单向不可逆(不能从密文获取明文),此时呢针对MD5这种加密方式可以使用暴力破解的方式进行破解

加盐加密

加盐加密算法(Salt Encryption)是一种对称密钥加密算法,它使用一个随机生成的盐(salt)作为加密和解密的关键参数,在加密过程中,将明文和盐作为输入,通过哈希函数计算出一个密文和一个盐值,在解密过程中,使用相同的盐值和密文计算哈希值,然后再用哈希值和盐值进行解密操作,以获取原始的明文

MD5+盐值加密

加密:我们可以使用一个随机字符串(盐值)和明文密码组合起来,作为带盐值的明文密码,再使用MD5对带盐值的密码进行加密

解密:解密其实就是判断用户需要校验密码的正确性

此时需要用到加密使用的盐值,这个盐值如何获取呢?

我们在数据库存储密码时存储盐值+密文,使用一个特定的分割符将盐值和密文分隔开,我们从数据库获取到密码的密文后,也使用同样的规则获取到盐值,使用该盐值和校验的密码重新使用MD5生成密文,判断新生成的密文和数据库保存的密文是否一致,如果是一致说明密码正确,否则密码错误

加密解密的代码实现:

public class PasswordTools {

    /**
     *加盐加密
     * @param password
     * @return 加密后的密码
     */
    public static String encrypt(String password){
        //生成盐值,使用随机字符串UUID,UUID为32位的
        String salt = UUID.randomUUID().toString().replace("-","");
        //(盐值+密码)进行MD5加密,DigestUtils.md5DigestAsHex参数为字节数组,生成一个十六进制32位的字符串
        String finalPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));
        //将盐值和加密的密码组合返回,最终存储到数据库中的密码
        String dbPassword = salt + "$" + finalPassword;
        return dbPassword;
    }

    /**
     * 校验密码
     * @param password
     * @param dbPassword
     * @return
     */
    public static boolean decrypt(String password,String dbPassword){
       if(StringUtils.hasLength(password) && StringUtils.hasLength(dbPassword)
               && dbPassword.length()==65 && dbPassword.contains("$")){
            String[] arr = dbPassword.split("\\$");
            String salt = arr[0];
            //根据获取的盐值生成校验的密码
            String checkPassword = salt + "$" + DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));
            //用校验密码与数据库保存的密码进行校验
            if(checkPassword.equals(dbPassword)){
                return true;
            }
        }
       return false;
    }

    public static void main(String[] args) {
        String dbPassword = encrypt("12345");
        System.out.println(decrypt("12345",dbPassword)); //true
        System.out.println(decrypt("45678",dbPassword)); //false
    }
}

Spring Security加盐

1.添加Spring Security依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

2.关闭Spring Security的认证

在启动类上的注解添加排除,禁止Spring boot启动时自动加载Spring Security框架

@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
public class DemoApplication {
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
}

3.使用BCryptPasswordEncoder对象提供的encode(String password)加密,和matches(String password,String dbPassword)解密方法

        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = "123456";
        System.out.println(passwordEncoder.encode(password));
        System.out.println(passwordEncoder.encode(password));
        System.out.println(passwordEncoder.encode(password));

        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = "123456";
        String dbPassword = passwordEncoder.encode(password);
        boolean result1 = passwordEncoder.matches(password,dbPassword); //正确的密码
        boolean result2 = passwordEncoder.matches("12345",dbPassword); //错误的密码
        System.out.println(result1);
        System.out.println(result2);

到此这篇关于Java实现加盐加密算法的示例详解的文章就介绍到这了,更多相关Java加盐加密算法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java如何获取Date的“昨天”与“明天”示例代码

    Java如何获取Date的“昨天”与“明天”示例代码

    最近在做项目的时候用到Date和Calendar比较多,而且用到的方式也比较全,突然想到一个问题,Java如何获取Date的"昨天"与"明天",也就是前一天和后一天呢?思考后写出了方法,想着万一以后用到,就总结出来,也方便有需要的朋友们参考借鉴,下面来一起看看吧。
    2016-12-12
  • java实现手机短信验证的基本思路

    java实现手机短信验证的基本思路

    这篇文章主要为大家详细介绍了java实现手机短信验证的基本思路,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Java详解Swing中的几种常用按钮的使用

    Java详解Swing中的几种常用按钮的使用

    这篇文章主要介绍了怎么用Java来创建和使用Swing中的几种常用按钮,按钮是我们经常要用的工具,但是你有想过自己怎么去实现它吗,感兴趣的朋友跟随文章往下看看吧
    2022-04-04
  • java面向对象之人机猜拳小游戏

    java面向对象之人机猜拳小游戏

    这篇文章主要为大家详细介绍了java面向对象之人机猜拳小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • mybatis mapper.xml中如何根据数据库类型选择对应SQL语句

    mybatis mapper.xml中如何根据数据库类型选择对应SQL语句

    这篇文章主要介绍了mybatis mapper.xml中如何根据数据库类型选择对应SQL语句,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • java中关于return返回值的用法详解

    java中关于return返回值的用法详解

    在本篇文章里小编给大家整理的是一篇关于java中关于return返回值的用法详解内容,有兴趣的朋友们可以学习参考下。
    2020-12-12
  • 基于IDEA创建SpringMVC项目流程图解

    基于IDEA创建SpringMVC项目流程图解

    这篇文章主要介绍了基于IDEA创建SpringMVC项目流程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • 基于idea解决springweb项目的Java文件无法执行问题

    基于idea解决springweb项目的Java文件无法执行问题

    这篇文章给大家介绍了基于idea解决springweb项目的Java文件无法执行问题,文中通过图文结合的方式给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-02-02
  • MyBatis一级缓存与二级缓存原理与作用分析

    MyBatis一级缓存与二级缓存原理与作用分析

    mybatis-plus是一个Mybatis的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发、提高效率而生,这篇文章带你了解Mybatis的一级和二级缓存
    2022-12-12
  • Java Jmeter全局变量设置过程图解

    Java Jmeter全局变量设置过程图解

    这篇文章主要介绍了Java Jmeter全局变量设置过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05

最新评论