본문 바로가기
system_fundamentals/security_cryptography

Salt는 왜 필요한가

by 죄니안죄니 2026. 5. 13.
반응형

비밀번호 암호화에서 솔트(Salt, 소금) 가 필수적인 이유는 크게 두 가지의 치명적인 해킹 공격을 무력화하기 위해서입니다.

1. 레인보우 테이블(Rainbow Table) 공격 방어

가장 핵심적인 이유입니다. 해커들은 누군가의 비밀번호를 알아내기 위해 그때그때 암호화를 돌려보지 않습니다. 대신, 1234, password, admin 같은 수십억 개의 흔한 비밀번호와 그것들의 '해시값(암호문)'을 미리 계산해서 엑셀 표처럼 만들어둔 거대한 데이터베이스를 가지고 있는데, 이를 레인보우 테이블이라고 부릅니다.

  • Salt가 없을 때: DB가 털리면, 해커는 암호문(예: 5d414...)을 자신의 레인보우 테이블에서 Ctrl+F로 검색합니다. 단 1초 만에 "아, 이 암호문은 password 구나" 하고 뚫려버립니다.
  • Salt가 있을 때: 사용자가 password라고 입력해도, 시스템이 임의의 난수(예: x9Qz)를 덧붙여서 passwordx9Qz를 암호화합니다. 해커의 레인보우 테이블에는 passwordx9Qz에 대한 암호문이 계산되어 있지 않기 때문에, 테이블 자체가 완전한 무용지물이 됩니다.

2. 동일한 비밀번호를 가진 사용자 식별 방지

솔트는 사용자마다 완전히 다른 고유한 난수로 생성되어 저장됩니다.

  • Salt가 없을 때: A유저와 B유저가 똑같이 0000을 비밀번호로 쓰면, DB에 저장된 암호문도 100% 똑같이 생겼습니다. 만약 해커가 A유저의 비밀번호가 0000이라는 걸 어떤 경로로든 알아냈다면, DB에서 A유저와 똑같은 암호문을 가진 다른 모든 유저들의 비밀번호도 0000이라는 것을 자동으로 알게 됩니다.
  • Salt가 있을 때: A유저(0000 + Salt 1번)와 B유저(0000 + Salt 2번)의 최종 암호문이 완전히 다르게 생성됩니다. 해커는 데이터베이스만 봐서는 누가 같은 비밀번호를 쓰는지 절대 유추할 수 없습니다.

📝 요약하자면

음식에 소금(Salt)을 치면 원재료가 같아도 맛이 확 달라지듯이, **"비밀번호가 같아도, 소금을 쳐서 암호문의 생김새를 매번 완전히 다르게 만드는 것"**이 솔트의 역할이며, 현대 웹 보안에서 선택이 아닌 필수 요소입니다.

 

 


 

💡 salt는 어디에서 관리될까?


보통 salt는 서비스 서버(DB 포함)가 관리해.

사용자가 따로 가지고 있는 값이 아니야.

많은 사람들이 여기서 헷갈리는데 구조를 차근차근 보면 이해돼.


1. salt는 왜 필요한가

비밀번호를 그냥 해시하면 문제가 생겨.

예를 들어:

password123
 

를 SHA-256 하면 항상 같은 결과가 나와.

ef92b7...
 

그러면 공격자가 미리 엄청난 해시 테이블(레인보우 테이블)을 만들어 둘 수 있어.


그래서 salt를 붙여.

예:

salt = x8KqP2z!
password = password123
 

실제로는:

x8KqP2z!password123
 

이걸 해시함.

그러면 같은 비밀번호라도 사람마다 결과가 달라져.


2. salt는 누가 생성하나

회원가입 시 서버가 랜덤 생성해.

예:

salt = 랜덤 16바이트
 

보통 CSPRNG(암호학적 난수 생성기) 사용.

예시:

 
SecureRandom
 
 
crypto.randomBytes()
 

같은 것들.


3. salt는 어디 저장하나

보통 DB에 같이 저장해.

예:

id salt password_hash
user1 x8KqP2z! abcd1234...

즉:

salt는 숨기는 값이 아니다
 

이게 핵심이야.


4. 그럼 salt가 유출되면 위험한거 아냐?

많이 오해하는 부분인데:

salt는 원래 공개되어도 되는 값
 

이야.

중요한 건:

비밀번호 원문
 

이지 salt 자체가 아니야.


salt의 목적은:

같은 비밀번호라도
서로 다른 해시 결과를 만들게 하는 것
 

이거야.

즉 공격자가:

password123 → ??? hash
 

를 미리 대량 계산 못하게 만드는 역할.


5. 로그인 시 어떻게 검증하나

예를 들어 DB에:

salt = x8KqP2z!
hash = AAAAA
 

가 저장되어 있다고 해보자.

사용자가 로그인 시:

password123 입력
 

하면 서버는:

x8KqP2z! + password123
 

를 다시 해시함.

결과가 DB의 hash와 같으면 로그인 성공.


6. 핵심은 “salt는 비밀이 아니다”

실무에서 개념적으로는:

salt = 공개 가능
hash = 저장
password = 절대 저장 금지
 

이 구조야.


7. 진짜 중요한 건 hash 알고리즘

그래서 요즘은 단순 SHA-256 쓰면 안 되고:

  • bcrypt
  • scrypt
  • Argon2

같은 느린 해시를 사용해.

왜냐면 GPU 병렬 공격을 느리게 만들기 위해서야.

특히 Argon2는:

CPU + 메모리까지 많이 사용하게 강제
 

해서 최신 권장 방식으로 많이 본다.


8. pepper는 또 다른 개념

salt와 별개로:

pepper
 

라는 것도 있음.

이건:

서버만 아는 비밀 키
 

야.

예:

hash(password + salt + pepper)
 

여기서 pepper는:

  • DB가 아니라
  • 서버 환경변수나 HSM 등에 저장

함.

즉:

개념 공개 가능 여부 저장 위치
salt 공개 가능 DB
pepper 비밀 서버 환경변수/HSM

이 차이가 있어.

 

💡특정사용자의 salt가 노출되어도 해킹이 쉽게 되는거 아니겠지?

salt 값과 hash 값을 둘 다 알아도
원래 비밀번호를 바로 알 수는 없어
 

왜냐면 해시는 “복호화”가 아니라 “추측 검증” 방식이기 때문이야.

차근차근 보면 이해돼.


1. 공격자가 DB를 털었다고 가정

예를 들어 DB에 이런 게 있다고 해보자.

id salt hash
user1 abc123 8f4e...

공격자는 이제:

  • salt = abc123
  • hash = 8f4e...

를 모두 알게 됨.


2. 그런데 해시는 복호화가 안됨

AES 같은 건:

암호화 → 복호화 가능
 

인데,

해시는:

입력 → 고정 결과
 

만 가능해.

즉:

password123 → 8f4e...
 

는 가능하지만,

8f4e... → password123
 

는 불가능해.


3. 그래서 공격자는 “추측”해야 함

공격 방식은 사실상 이거야.

guess = "123456"
hash(salt + guess)

결과 비교
 

틀림.

다시:

guess = "password123"
hash(salt + guess)
 

맞음.

즉:

무한 대입 공격(brute force)
 

밖에 방법이 없어.


4. salt가 없으면 왜 위험한가

여기서 salt의 진짜 역할이 나와.

만약 salt가 없으면:

user hash
A aaa
B aaa

둘 다 같은 비밀번호라는 걸 즉시 알 수 있음.

그리고 공격자는 미리 이런 테이블을 만들 수 있어.

password hash
123456 xxx
password123 aaa

이걸:

레인보우 테이블
 

이라고 해.

그러면 DB 털자마자 바로 역매핑 가능.


5. salt가 있으면 뭐가 달라지나

각 사용자마다:

salt가 다름
 

예:

user salt hash
A abc xxx
B def yyy

같은 비밀번호여도 결과가 달라짐.

공격자는 이제:

모든 사용자에 대해
개별적으로 brute force 해야 함
 

즉:

미리 계산 공격이 불가능
 

해져.


6. 핵심은 “비밀번호 자체는 여전히 비밀”

공격자가 알아도 되는 건:

  • salt
  • hash

까지야.

하지만 진짜 필요한 건:

원문 password
 

인데 이건 계산으로 바로 못 얻어.


7. 그래서 bcrypt/Argon2가 중요한 이유

현대 시스템은 단순 SHA-256 안 쓰고:

  • bcrypt
  • scrypt
  • Argon2

를 쓰는 이유가 여기 있어.

이 알고리즘들은 일부러:

해시 계산을 느리게 만듦
 

예:

1회 계산 = 100ms
 

그러면 공격자가:

10억 번 brute force
 

하는 게 엄청 느려져.


8. 실제 보안은 결국 “비밀번호 강도”도 중요

만약 사용자가:

123456
 

같은 비밀번호를 쓰면,

salt가 있어도 결국 brute force로 금방 뚫림.

반면:

Kq!9xL2@vP#7
 

같은 건 현실적으로 매우 어려워짐.


최종 정리

salt는 숨기는 값이 아니라
사용자마다 해시 결과를 다르게 만들어
대량 사전공격을 막는 장치
 

이고,

실제 보안의 핵심은:

1. 느린 해시 알고리즘(bcrypt/Argon2)
2. 강한 비밀번호
 

이 두 개야.

 

🔗 보안_암호학 목차로 

반응형

댓글