CS 면접을 준비하기 위해 개인적으로 정리하고 있습니다. 혹시라도 내용이 잘못되거나 미흡한 것이 있다면 알려주시면 감사드리겠습니다.
비밀번호를 왜 해싱할까?
만약 사용자 계정 정보가 담긴 데이터베이스가 해킹당한다면, 해커는 쉽게 사용자 아이디와 비밀번호를 탈취할 수 있다. 특히나 비밀번호가 평문(plaintext) 상태로 저장되어 있다면 큰 피해로 이어질 수 있다. 해커가 탈취한 비밀번호로 계정 탈취, 피싱, 금융 사기 등 2차 피해를 발생시키는 경우가 많기 때문이다.
따라서 비밀번호는 절대 평문 상태로 데이터베이스에 저장해서는 안 되며, 해커의 탈취 시도에 대비하여 안전한 방식으로 관리해야 한다. 그 방법 중 하나가 바로 해싱(hashing)이다.
비밀번호 해싱이란?
해싱은 입력된 데이터를 고정된 길이의 값(해시값)으로 변환하는 과정이다. 이때 해시 알고리즘을 통해 변환된 값은 단방향이며, 변환된 값을 다시 원본으로 복구하는 것은 불가능하다.
하지만 단순히 해시 함수만 사용해도 해커가 동일한 해시값을 예측할 수 있는 문제가 생길 수 있다. 이때 해커는 사전 공격(Dictionary Attack) 또는 브루트 포스 공격을 통해 비밀번호를 알아내려 시도한다. 이를 막기 위해 솔트(salt)와 느린 해시 알고리즘을 사용하는 것이 중요하다.
솔트
솔트(salt)는 각 사용자 비밀번호마다 랜덤 하게 생성되는 문자열이다. 이 솔트 값을 비밀번호에 추가해서 해시를 생성하면, 같은 비밀번호라도 매번 서로 다른 해시값이 생성된다.
위 그림은 똑같은 비밀번호를 가지는 두 사용자의 해시 값을 솔트 유무로 구분하여 나타낸다. 솔트 없이 해싱하면 같은 해시 값이 나오나, 사용자마다 다르게 생성된 솔트로 인해 해시 값이 달라지는 것을 확인할 수 있다.
Bcrypt
실제로 백엔드 개발을 하다 보면 Bcrypt 알고리즘을 사용해서 사용자 비밀번호를 해싱하는 경우가 많다. 왜 그런지 알아보자.
만약 나 같은 초보 개발자 분들이 계시다면, 질문을 드리고 싶다. 서비스를 개발하면서, 해싱을 할 때 솔트 값을 신경 쓴 적이 있는가?
만약 없다면, 여러분은 Bcrypt 알고리즘이 제공하는 장점을 매우 잘 활용했던 것이다.
Bcrypt는 다음과 같은 특징을 가진다.
1. 느린 해싱: 해시 계산 속도가 느리기 때문에 브루트포스 공격을 어렵게 만든다.
2. 내장 솔트 사용: 자동으로 랜덤 솔트 값을 생성해 해시 값에 포함하기 때문에, 솔트를 따로 관리하거나 테이블에 저장할 필요가 없다.
Bcrypt 해시에는 솔트 값이 자동으로 포함되기 때문에, 해시 생성 때마다 새로운 솔트가 자동으로 생성되어 동일한 비밀번호라도 매번 다른 해시 값이 나온다. 따라서, 실제로는 솔트 값을 사용하지만 개발하는 입장에서는 별도의 솔트 값을 저장하지 않아도 되는 편의성이 있다.