이번에 작성할 주제는 Spring Security의 PasswordEncoder를 공부하며 생긴 Bcrypt와 salt에 대한 궁금증을 해소하며 공부한 내용을 정리할 것이다.
Bcrypt를 이용하여 PasswordEncoder를 구현하다 보니, Bcrypt에 대해서 공부하게 되었고 Bcrypt는 Rainbow Table 같은 사전 계산된 해시값의 대규모 데이터베이스를 이용한 브루트 포스 공격에 방지하기 위해, 입력값에 'salt'라는 랜덤 값이 추가되어 해싱 과정을 거치게 된다는 것을 알게되었다.
하지만 salt를 이용하면 후에 저장되어있는 비밀번호와 사용자가 입력한 비밀번호를 비교하여야 하는데 salt를 어디에 저장해 놓지도 않고 어떻게 비교할까에 대한 궁금증이 들었고 여러가지 자료를 찾아보다가 아래 게시글을 발견하였다. 나의 똑같은 궁금증을 가진 사람을 위해 아래 게시글의 링크를 작성하고 넘어가겠다.
해당 게시글과 마찬가지로 해시값에 salt 값을 저장하는 것이 보안에 위험하지 않을까 고민했다. 하지만, salt의 주 목적을 생각해보면, 이미 계산된 Rainbow Table을 무용지물로 만드는 것이다. 이 목적 아래에서 salt값을 해시값과 함께 저장하는 것은 보안에 큰 위협이 되지 않는다는 결론이다.
또한 Salt는 각 사용자 비밀번호에 대해 고유한 추가값을 제공해, 모든 사용자의 고유 해시 값을 생성한다. 이는 공격자가 특정 해시값을 대상으로 사전 계산된 Rainbow Table을 이용한 공격을 불가능하게 만든다. 그리고 Bcrypt는 해시 계산에 상당 시간을 소모하도록 설계되어 있어, 각각의 salt에 대한 새로운 Rainbow Table 생성은 비현실적이라고 생각한다.
이러한 이해를 통해 Spring Security의 Bcrypt와 salt 사용 방식이 얼마나 효과적이고 신중하게 설계되었는지 알 수 있게 되었고, 이 지식을 바탕으로, 보안에 대한 더 나은 결정을 내릴 수 있게 되었다.