12.스프링 시큐리티(3) 비밀번호 암호화 vs 해시

Alex·2024년 6월 22일
0

이슈 트래커

목록 보기
8/21

스프링 시큐리티 인 액션을 보고서
비밀번호를 암호화하는 방식을 구현했다.

책을 참고해서 암호화 방식을 구현했는데, 비밀번호는 복호화가 불가능한 해시를 사용하는 것이 더 좋다는 말을 들었다.

해싱과 암호화는 데이터 보안에 사용되는 개념으로,
Hash는 단방향 암호화 기법 Encryption은 양방향 암호화 기법이다.

Hash는 복호화가 불가능해서, 비밀번호를 저장할 때 탈취의 가능성을 염두에 둔다면 사용할 수 있는 단방향 암호화 방식이다. 같은 데이터를 동일한 해시 알고리즘으로 암호화할 때 항상 같은 결과가 나오기에 복호화가 불가능해도 사용자 인증이 가능하다.

Why Hashing is preferred in spring security for password encryption ?

암호화는 서버 관리자나 개발자가 알고리즘과 키를 알면 암호화된 데이터를 쉽게 복호화할 수 있다.

해시의 경우, 한번 해싱된 데이터는 원래의 형식으로 복원할 수 없다. 해시 값을 갖고 있어도 원래의 데이터를 알아낼 수 없어서 보안성이 높다.

[Spring] 비밀번호 암호화에 대한 고찰
이글과 스프링 시큐리티 공식문서를 보니 Rain table이라는 문제가 여전히 존재하는 거 같다.

모든 비밀번호에 대해 해시값을 기록하고 무차별적으로 공격하는 것을 레인보우 테이블이라고 한다. 시간이 걸리더라도 언젠가는 뚫릴 수 있는 것.

이를 막기 위해서는 해쉬 함수를 만들기 전에 평문값에 salt라는 랜덤값을 추가로 넣어서 해시 함수를 만들 수 있다.

[Spring Security] Bcrypt의 salt는 무엇일까?

이 글을 보면서 BCryptEncoder가 내부적으로 처리를 해주는 것을 알게 됐다. 비밀번호와 같이 salt가 해시처리된다.

@Service
@RequiredArgsConstructor
public class UserService {

    private final BCryptPasswordEncoder bCryptPasswordEncoder;
    private final UserRepository userRepository;

    public Long save(JoinRequestServiceDto requestDto){

        String hash = bCryptPasswordEncoder.encode(requestDto.getPassword());
        User user = new User(requestDto.getLoginId()
                , requestDto.getName()
                , hash
                , requestDto.getAddress()
                , requestDto.getBirthdate());

       return userRepository.save(user).getId();
    }


}

테스트를 해보니 실제로 비밀번호가 해시로 암호화돼서 돌아갔다.
그리고 match 메서드를 사용하니 비밀번호를 복호화하는 과정없이도 유저의 credential을 확인할 수 있었다.

match 메서드가 실제로 잘 작동하는건지 확인하기 위해서 실패하는 테스트도 작성했다.

테스트는 무사히 통과했다!

profile
답을 찾기 위해서 노력하는 사람

0개의 댓글