개요[편집 / 원본 편집]

솔트(Salt)암호학에서 패스워드 등의 데이터를 해시할 때 원본 데이터에 추가하는 랜덤한 문자열이다. 요리할 때 넣는 그 소금 맞다

솔트의 주된 목적은 레인보우 테이블 공격을 방지하고, 동일한 패스워드라도 서로 다른 해시값을 생성하게 하는 것이다. 같은 비밀번호 쓰는 사람들 많은데 해시값까지 똑같으면 곤란해 버리기 때문이다.

작동 원리[편집 / 원본 편집]

일반적인 해시 과정:

패스워드: "password123"
해시값: 482c811da5d5b4bc6d497ffa98491e38

솔트를 사용한 해시 과정:

패스워드: "password123"
솔트: "aB3$xY9z"
결합: "password123aB3$xY9z"
해시값: 7d865e959b2466918c9863afca942d0f

이렇게 하면 같은 패스워드라도 솔트가 다르면 완전히 다른 해시값이 나온다. 마력소비 아니 전기 소비 마법

필요성[편집 / 원본 편집]

레인보우 테이블 공격 방지[편집 / 원본 편집]

레인보우 테이블은 자주 사용되는 패스워드들의 해시값을 미리 계산해둔 거대한 치트시트다. 게임 공략집 같은 거라고 보면 된다.

솔트 없이 해시된 패스워드:

  • "123456" → 해시값 A
  • "password" → 해시값 B
  • "qwerty" → 해시값 C

공격자가 해시값 A를 보면 즉시 "123456"이라는 걸 알 수 있다. 보안이고 뭐고 없다

솔트를 사용하면:

  • "123456" + 솔트1 → 해시값 X
  • "123456" + 솔트2 → 해시값 Y
  • "password" + 솔트3 → 해시값 Z

이제 공격자는 각각의 솔트에 대해 개별적으로 레인보우 테이블을 만들어야 한다.

동일 패스워드 구분[편집 / 원본 편집]

솔트가 없다면:

  • 사용자 A: "password123" → 해시값 같음
  • 사용자 B: "password123" → 해시값 같음

솔트를 사용하면:

  • 사용자 A: "password123" + 솔트A → 해시값 다름
  • 사용자 B: "password123" + 솔트B → 해시값 다름

이제 설령 같은 비밀번호를 써도 티가 안 난다. 프라이버시 보호 완료

구현 방법[편집 / 원본 편집]

솔트 생성[편집 / 원본 편집]

솔트는 반드시 암호학적으로 안전한 난수 생성기로 만들어야 한다.

  • 길이: 최소 16바이트 (128비트) 이상 권장
  • 유일성: 각 사용자마다 고유한 솔트 사용
  • 예측 불가능성: 그냥 "salt123" 이런 거 쓰면 안 된다고

저장 방식[편집 / 원본 편집]

일반적으로 솔트와 해시값을 함께 저장한다:

사용자ID | 솔트 | 해시값
user1 | aB3$xY9z | 7d865e959b2466918c9863afca942d0f
user2 | mN8&vC2k | f4a8b2c9e1d3f7e5a6b9c8d2e1f4a7b6

솔트가 공개되어도 상관없다.[1] 어차피 솔트의 목적은 비밀 유지가 아니라 레인보우 테이블 무력화이기 때문이다.

주의사항[편집 / 원본 편집]

하면 안 되는 것들[편집 / 원본 편집]

  • 전역 솔트 사용하기. 모든 사용자가 같은 솔트 쓰면 의미없음
  • 짧은 솔트 사용하기
  • 예측 가능한 솔트 사용하기[2]
  • 솔트 재사용 하기

올바른 방법[편집 / 원본 편집]

  • 각 패스워드마다 새로운 솔트 생성
  • 충분한 길이의 솔트 사용 (16바이트 이상)
  • 암호학적으로 안전한 난수 생성기 사용
  • 솔트와 해시값 모두 저장

관련 기술[편집 / 원본 편집]

솔트 내장 해시[편집 / 원본 편집]

bcrypt, scrypt, Argon2 등은 솔트 기능을 내장한 패스워드 해싱 함수들이다. 솔트 생성과 해시 계산을 안전하게 자동 처리하며, 반복 횟수 조절 등으로 브루트포스 공격에도 강하다. 직접 솔트와 해시를 구현하다가는 보안 결함이 생기기 쉬우므로, 검증된 알고리즘을 사용하는 것이 안전하다.

  • 자동 솔트 생성
  • 느린 해싱 (브루트포스 방지)
  • 검증된 보안성

펩퍼(Pepper)[편집 / 원본 편집]

솔트의 상위 호환 개념으로, 서버의 비밀 키를 추가로 사용한다.

  • 솔트: 공개되어도 됨. 근데 굳이 공개할 필욘 없긴 하다.[1]
  • 펩퍼: 절대 공개되면 안 됨. 해시 계산 시 비밀 키처럼 쓰이는 값이다.[3] 솔트는 공격 지연용 공개 정보, 펩퍼는 공격 차단용 비밀 정보이기에 솔트와 동일선상에서 비교하기엔 무리이다. 또한 DB서버와 동일한 서버에 저장해 두면 절대 안된다. 해커가 DB뿐만 아니라 웹서버 또는 애플리케이션 서버까지 장악했을 경우, 펩퍼까지 유출되어 패스워드를 복구당할 수 있다. 해시 알고리즘이 아무리 강해도 의미 없어진다.


여담[편집 / 원본 편집]

  • 솔트라는 이름은 요리에서 간을 맞추는 소금에서 따온 것이다.
  • 초기 UNIX 시스템에서는 솔트 길이가 고작 12비트(!)였다. 지금 기준으론 장난감 수준. 요즘은 최소 128비트 솔트가 표준이다.

관련 문서[편집 / 원본 편집]

각주[편집 / 원본 편집]

  1. 1.0 1.1 일반적으로 솔트는 DB 내부에서만 사용되므로 대중에게 보여줄 이유가 없다. 공개한다고 도움이 되진 않는다. 만약 해시 함수가 약하거나, 사용자 비밀번호가 단순하다면, 솔트+해시가 같이 유출되었을 때 브루트포스에 위험하다.
  2. 예: 특정값(1234 등)
  3. 예: 해시(패스워드 + 펩퍼) 또는 해시(펩퍼 + 패스워드 + 솔트)