登录密码的加密算法

444 阅读2分钟

md5算法

彩虹表攻击:

简单来说,由于每次md5算法生成的数据都是唯一的,例如:密码:123,对应生成的密文就是abc那么无论什么情况下,利用md5加密后123都与abc相对应,只需要将密码对应生成的密文与密码一一对应,并列出一个表,表中的数据与你的密码相对应,就能找到你设置的密码,这就是彩虹表攻击

 /**
     * md5 加密算法
     * 每次加密后的值都是相同的,不能防御 彩虹表攻击
     */
    @Test
    public void md5(){
        //需要加密的数据
        String sourceString ="123456";
        String s = DigestUtils.md5DigestAsHex(sourceString.getBytes());
        System.out.println("第一次加密"+s);
        s = DigestUtils.md5DigestAsHex(sourceString.getBytes());
        System.out.println("第二次加密"+s);
    }
/* 第一次加密e10adc3949ba59abbe56e057f20f883e
        第二次加密e10adc3949ba59abbe56e057f20f883e*/

bcrypt 算法

为了防止出现md5的漏洞,bcrypt加密算法,每一次加密时对应生成的密文都是不相同的,这样就有效的防止了彩虹表的攻击。

    /**
     *bcrypt算法可以避免彩虹表攻击
     */
    @Test
    public void bcrypt(){
        //需要加密的数据
        String sourceString="123456";
        BCryptPasswordEncoder bCryptPasswordEncoder =new BCryptPasswordEncoder();
        //生成密文
        String code =bCryptPasswordEncoder.encode(sourceString);

        System.out.println("第一次加密"+code);
        boolean matches =bCryptPasswordEncoder.matches(sourceString,code);
        System.out.println("第一次验证 = " + matches);

        code = bCryptPasswordEncoder.encode(sourceString);
        System.out.println("第二次加密"+code);
        matches=bCryptPasswordEncoder.matches(sourceString,code);
        System.out.println("第二次验证 = " + matches);
    }
    /*  第一次加密$2a$10$GTjKSntdpVg9zZoZuzz/dOhTnv0A/3ICmD.s97M/F/Ye.RO70aJT6
        第一次验证 = true
        第二次加密$2a$10$xBBVP/aUp9A0dfkLkETi8.TT7BeWTr2lguAYVe8iwiRMi24Y4DjJq
        第二次验证 = true*/

bcrypt 算法应用

应用场景:注册时对密码的加密

在pom文件中导入依赖

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-crypto</artifactId>
    <version>5.3.2.RELEASE</version>
    <scope>test</scope>
</dependency>

在启动类中向spring容器注入PasswordEncoder,保证在项目中只需要生成一次PasswordEncoder对象,可以避免重复生成,所有项目用一个就可以了

    //引入bcrypt算法加密数据
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

然后在service中对需要加密的数据进行加密

首先利用@Resource注解注入passwordEncoder

    @Resource
    private PasswordEncoder passwordEncoder;

其次实现具体逻辑

@Service
public class UmsMemberServiceImpl implements UmsMemberService {

    @Resource
    private UmsMemberMapper umsMemberMapper;
    @Resource
    private PasswordEncoder passwordEncoder;

    public String register(UmsMemberRegisterParamDTO umsMemberRegisterParamDTO){

        UmsMember umsMember = new UmsMember();
        //将前端传来的对象转化为数据库存储的对象
        BeanUtils.copyProperties(umsMemberRegisterParamDTO,umsMember);

        //利用bCrypt算法加密密码

        //生成密文
        //String encode = passwordEncoder.encode(umsMemberREgisterParamDTO.getPassword());
        String encode = passwordEncoder.encode(umsMember.getPassword());

        umsMember.setPassword(encode);

        umsMemberMapper.insert(umsMember);

        return "success";
    }
    
}

在简单登陆中实现运用bcrypt算法

    public String login(UmsMemberLoginParamDTO umsMemberLoginParamDTO) {

        System.out.println("开始登录!!!!");
        UmsMember umsMember = umsMemberMapper.selectByName(umsMemberLoginParamDTO.getUsername());
        if(null!=umsMember){
            //获得密码
            String passwordDb= umsMember.getPassword();
            //利用bcrypt算法验证密码
            if(!passwordEncoder.matches(umsMemberLoginParamDTO.getPassword(),passwordDb)){
                return "密码不正确!!";
            }
        }else {
            return "用户不存在!!";
        }
        return "token";
    }