Springboot

[SpringSecurity] BCrypt 비밀번호 인증 구현

코딩 못하는 감자 2025. 3. 12. 00:03

BCrypt

Bcrypt 해싱 기법은 내부적으로 Salt(무작위 문자열)을 추가하기 때문에 매번 다른 결과를 만들어내는 기법이다.

보통 해시함수로 이루어진 비밀번호는 이전의 비밀번호를 추가로 해시하여 값을 비교하지만, 이경우에는 어떻게 비밀번호를 검증해야 하는지 궁금증이 생기게 되었다.

PasswordEncoder 빈 등록

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

잘못된 코드

  public void unregisterUser(Long userId, String password) {
      UserEntity userEntity=userService.getUserById(userId);
      var encodePassword=passwordEncoder.encode(password);

      if(!userEntity.getPassword().equals(encodePassword)) {
          throw new ApiException(UserErrorCode.INVALID_PASSWORD);
      }

      userService.deleteUser(userId);
  }

다른 해시 함수의 경우 이런식으로 입력한 값을 해싱하여 값을 비교한다.

하지만 이 경우 저장된 해시값과 다른값이 나오기 때문에 예외가 발생하게 된다.

수정된 코드

  public void unregisterUser(Long userId, String password) {
      UserEntity userEntity=userService.getUserById(userId);
      
      if (!passwordEncoder.matches(password, userEntity.getPassword())) {
          throw new ApiException(UserErrorCode.INVALID_PASSWORD);
      }

      userService.deleteUser(userId);
  }

PageEncoder는 비밀번호를 비교하는 matches 메서드를 제공한다.

저장된 해시값으로부터 Salt 값을 가져오고, 이 값을 바탕으로 해싱하여 비밀번호 검증절차를 거친다.

따라서 정상적으로 값 비교가 가능해진다.