Salting이란 무엇인가
Salting은 비밀번호를 해시(hash)로 저장할 때, 원본 비밀번호에 임의의 무작위 문자열인 ‘솔트(salt)’를 덧붙인 뒤 해시 함수를 적용하는 기법입니다. 요리할 때 소금을 뿌려 맛을 내듯, 비밀번호에 예측 불가능한 값을 더해 보안성을 높인다는 의미에서 이런 이름이 붙었습니다. 예를 들어 사용자가 1234라는 비밀번호를 입력했다면, 서버는 이를 그대로 해시하지 않고 1234 + 무작위값(salt)을 합친 뒤 해시 함수를 돌려 저장합니다. 이렇게 하면 같은 비밀번호를 쓰는 두 사용자라도 서로 다른 솔트 덕분에 완전히 다른 해시값이 생성됩니다.
왜 Salting이 필요한가: 레인보우 테이블 공격 방어
해시 함수는 같은 입력에 항상 같은 출력을 내놓는 특성이 있습니다. 공격자는 이 점을 이용해 자주 쓰이는 비밀번호와 그 해시값을 미리 대량으로 계산해둔 ‘레인보우 테이블(rainbow table)’을 만들어, 유출된 해시값과 대조하는 방식으로 원본 비밀번호를 역추적합니다. 솔트가 없다면 1234의 해시값은 항상 동일하므로, 공격자는 미리 만든 표만 조회하면 순식간에 비밀번호를 알아낼 수 있습니다.
하지만 각 사용자마다 다른 솔트를 붙이면 상황이 달라집니다. 사용자 A의 1234+salt_A와 사용자 B의 1234+salt_B는 완전히 다른 해시값을 만들어내기 때문에, 공격자는 더 이상 하나의 테이블로 모든 계정을 공격할 수 없습니다. 사용자마다 새로운 레인보우 테이블을 만들어야 하는데, 이는 사실상 무차별 대입 공격과 다를 바 없는 수준의 비용을 요구합니다. 결국 Salting은 공격 난이도를 기하급수적으로 끌어올리는 효과를 냅니다.
실무에서의 적용과 주의점
실무에서는 개발자가 직접 솔트를 생성하고 관리하기보다, bcrypt, scrypt, Argon2 같은 검증된 비밀번호 해싱 라이브러리를 사용하는 것이 표준입니다. 이런 라이브러리들은 내부적으로 솔트를 자동 생성하고, 해시값과 함께 저장해 검증 시 다시 꺼내 쓸 수 있도록 처리해줍니다. 또한 이들 알고리즘은 연산 속도를 의도적으로 느리게 설계해, 공격자가 무차별 대입을 시도해도 시간이 오래 걸리도록 만듭니다.
- 솔트는 사용자마다 고유해야 하며, 재사용하면 안 됩니다.
- 솔트 자체는 비밀이 아니므로 해시값과 함께 저장해도 무방합니다.
- MD5, SHA-1처럼 빠른 범용 해시 함수는 비밀번호 저장 용도로 적합하지 않습니다.
결국 Salting은 ‘비밀번호를 얼마나 복잡하게 만드는가’가 아니라 ‘동일한 비밀번호도 서로 다르게 저장되도록 만드는가’에 초점을 맞춘 방어 기법입니다. 데이터베이스가 유출되더라도 해커가 실제 비밀번호를 알아내기까지 걸리는 시간과 비용을 극대화하는 것, 그것이 Salting의 핵심 목적입니다.