Spring

[Spring Security] BCryptPasswordEncoder 암호화된 비밀번호 검증 어떻게 할까?

돌맹이떼굴떼굴 2024. 11. 21. 19:26

1. 문제

스프링 시큐리티를 사용해서 비밀번호를 저장하면 암호화 되어 아래와 같이 Hash 로직에 의해 암호화 되서 들어간다.

저장은 했는데, 입력했을 때 비교는 어떻게 할까?

 

// 비밀번호 검증
public boolean authPassword(String email, String password) {
	// 이메일로 유저 검증
    Optional<User> optionalUser = userRepository.findByEmail(email);
    if (optionalUser.isPresent()) {
    	// 유저가 있다면 existsByPassword로 비교
        User user = optionalUser.get();
        String passwordHash = bCryptPasswordEncoder.encode(password);
        boolean exist = userRepository.existsByPassword(passwordHash);
        if (exist) return true;
        else return false;
    }
    return false;
}

처음 서비스 로직을 작성할 때 단순히 데이터베이스에서 바로 비교하거나 equals로 확인하면 안된다. 그 이유는 BCryptPasswordEncoder는 암호화를 수행할 때마다 랜덤 솔트를 추가해서 같은 비밀 번호도 매번 다른 해시값을 생성한다.

여기서 솔트 데이터는 비밀번호를 처리하는 단방향 함수의 추가 입력으로 사용되는 랜덤 데이터라고 한다.

출처 : 솔트(암호학) - 위키백과

 

BCrypt는 복호화가 불가능한 방식으로 위에서 단방향이라는 말이 암호화된 비밀번호를 반대로는 되돌릴 수 없다는 말이다.

 

2. 문제 해결

public boolean authPassword(String email, String inputPassword) {
Optional<User> optionalUser = userRepository.findByEmail(email);
if (optionalUser.isPresent()) {
    User user = optionalUser.get();
    // matches를 사용하여 입력 비밀번호와 저장된 해시값을 비교
    return bCryptPasswordEncoder.matches(inputPassword, user.getPassword());
}
return false; // 사용자 정보가 없으면 false 반환

inputPassword는 내가 확인하려고 넣은 비밀번호이고, user.getPassword( )는 DB에 들어 있는 비밀번호이다. BCryptPasswordEncoder에서 제공하는 matches 함수를 이용하면 위와 같이 간단하게 비교할 수 있다.

 

[결론] : 프로젝트 때문에 바빠서 글 못올렸는데 올릴게 산더미⛰️⛰️⛰️