目录
1.3.2在项目路径下创建一个tools包,在这个包中新建类
2.1.3在项目路径下创建一个tools包,在这个包中新建类
MD5是一个安全的散列算法,输入两个不同的明文不会得到相同的输出值,根据输出值,不能得到原始的明文,即其过程不可逆.但是虽然不可逆,但是不是说就是安全的。因为自从出现彩虹表后,这样的密码也"不安全"
彩虹表:彩虹表就是一个庞大的、针对各种可能的字母组合预先计算好的哈希值的集合,不一定是针对MD5算法的,各种算法的都有,有了它可以快速的破解各类密码。越是复杂的密码,需要的彩虹表就越大,现在主流的彩虹表都是100G以上
(盐是在每个密码中加入一些单词来变成一个新的密码,存入数据库当中)
- <dependency>
- <groupId>commons-codecgroupId>
- <artifactId>commons-codecartifactId>
- dependency>
- <dependency>
- <groupId>org.apache.commonsgroupId>
- <artifactId>commons-lang3artifactId>
- <version>3.9version>
- dependency>
这个路径是这样的:com.example.anitamusicspace.tools,我的这个项目叫anitamusicspace
- package com.example.anitamusicspace.tools;
-
- import org.apache.commons.codec.digest.DigestUtils;
-
- /**
- * Created with IntelliJ IDEA.
- * Description:
- * User: 小梅就是酱子
- * Date: 2022-08-02
- * Time: 15:28
- */
- public class MD5Util {
- //定义一个固定的盐值
- private static final String salt = "1b2i3t4e";
- public static String md5(String src) {
- return DigestUtils.md5Hex(src);
- }
- /**第一种方法
- * 第一次加密 :模拟前端自己加密,然后传到后端
- * @param inputPass
- * @return
- */
- public static String inputPassToFormPass(String inputPass) {
- String str = ""+salt.charAt(1)+salt.charAt(3) + inputPass +salt.charAt(5) + salt.charAt(6);
- return md5(str);
- }
- /**第一种方法
- * 第2次MD5加密
- * @param formPass 前端加密过的密码,传给后端进行第2次加密
- * @param salt 用户数据库当中的盐值
- * @return
- */
- public static String formPassToDBPass(String formPass, String salt) {
- String str = ""+salt.charAt(0)+salt.charAt(2) + formPass +salt.charAt(5) + salt.charAt(4);
- return md5(str);
- }
- /**第二种方法
- * 上面两个函数合到一起进行调用
- * @param inputPass
- * @param saltDB
- * @return
- */
- public static String inputPassToDbPass(String inputPass, String saltDB) {
- String formPass = inputPassToFormPass(inputPass);
- String dbPass = formPassToDBPass(formPass, saltDB);
- return dbPass;
- }
- public static void main(String[] args) {
- System.out.println("对用户输入密码进行第1次加密:"+inputPassToFormPass("123456"));
- System.out.println("对用户输入密码进行第2次加密:"+formPassToDBPass(inputPassToFormPass("123456"), "1b2i3t4e"));
- System.out.println("对用户输入密码进行第2次加密:"+inputPassToDbPass("123456", "1b2i3t4e"));
- }
- }
输出结果:
注:因为这里没有用随机盐值,所以不管运行多少次,这个密码是规定的。当密码长度很大,盐值也是随机的情况下,密码的强度也加大了。破解成本也增加了
Bcrypt就是一款加密工具,可以比较方便地实现数据的加密工作。你也可以简单理解为它内部自己实现了随机加盐处理
- <dependency>
- <groupId>org.springframework.securitygroupId>
- <artifactId>spring-security-webartifactId>
- dependency>
- <dependency>
- <groupId>org.springframework.securitygroupId>
- <artifactId>spring-security-configartifactId>
- dependency>
@SpringBootApplication(exclude ={org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class})
这个路径是这样的:com.example.anitamusicspace.tools,我的这个项目叫anitamusicspace
- package com.example.anitamusicspace.tools;
-
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-
- /**
- * Created with IntelliJ IDEA.
- * Description:
- * User: 小梅就是酱子
- * Date: 2022-08-02
- * Time: 16:06
- */
- public class BCryptTest {
- public static void main(String[] args) {
- //模拟从前端获得的密码
- String password = "123456";
- BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
- String newPassword = bCryptPasswordEncoder.encode(password);
- System.out.println("加密的密码为: "+newPassword);
- //使用matches方法进行密码的校验
- boolean same_password_result = bCryptPasswordEncoder.matches(password,newPassword);
- //返回true
- System.out.println("加密的密码和正确密码对比结果: "+same_password_result);
- boolean other_password_result = bCryptPasswordEncoder.matches("987654",newPassword);
- //返回false
- System.out.println("加密的密码和错误的密码对比结果: " + other_password_result);
- }
- }
解释:
输出结果:(可以看到,同一个密码,每次加密后都不一样)
(1)BCrypt加密: 一种加盐的单向Hash,不可逆的加密算法,同一种明文(plaintext),每次加密后的密文都不一样,而且不可反向破解生成明文,破解难度很大。
(2)MD5加密: 是不加盐的单向Hash,不可逆的加密算法,同一个密码经过hash的时候生成的是同一个hash值,在大多数的情况下,有些经过md5加密的方法将会被破解。
(3)Bcrypt生成的密文是60位的。而MD5的是32位的。
(4)目前,MD5和BCrypt比较流行。相对来说,BCrypt比MD5更安全(因为破解难度更大了),但加密更慢。 虽然BCrupt也是输入的字符串+盐,但是与MD5+盐的主要区别是:每次加的盐不同,导致每次生成的结果也不相同。两种加密方式无法对比
(5)BCrypt的破解增加了,就会导致系统的运行成本也增加
(6)最后需要知道的是,密码学的应用安全是建立在破解所要付出的成本远超过能得到的利益上的