4강 / 20강

비밀번호는 어떻게 저장해야 하나

해시 · 솔트 · 그리고 '일부러 느린' 해시

비밀번호는 어떻게 저장해야 하나
좋은 시스템은 여러분의 비밀번호를 모릅니다. 그래야 새어 나가도 지킬 수 있어요.

회원가입을 받으면 비밀번호를 저장해야 합니다. 그런데 어떻게 저장할까요? 가장 순진한 방법 — 입력한 그대로 DB에 넣는 것 — 은 최악입니다. DB가 한 번 새면(11강에서 실제로 뚫어 봅니다) 모든 회원의 비밀번호가 그대로 유출되거든요.

정답은 뜻밖입니다. 비밀번호를 저장하지 않는 것입니다. 대신 해시라는, 되돌릴 수 없는 지문만 저장합니다.

해시는 되돌릴 수 없는 지문입니다

해시 함수는 어떤 입력이든 정해진 길이의 값으로 바꿉니다. 특징이 둘이에요.

  • 같은 입력 → 항상 같은 출력 (그래서 로그인 확인에 쓸 수 있다)
  • 한 글자만 바꿔도 → 완전히 다른 출력 (눈사태 효과)
  • 출력 → 입력으로 되돌리기 불가능 (단방향)

직접 확인해 봅시다.

결과 아래 '눈사태 효과' 설명을 보세요.
🖥️ 내 가상 서버 브라우저 안에서 실행 (계산용)
브라우저 안에서 직접 해시해 봅니다.
Python 브라우저 안에서 실행 (계산용)

로그인은 이렇게 이뤄집니다

서버는 여러분의 비밀번호를 모릅니다. 그럼 어떻게 로그인을 확인할까요?

가입할 때
입력한 비번을 해시해서 그 해시만 저장. 원본은 버림
로그인할 때
입력한 비번을 같은 방법으로 해시해서, 저장된 해시와 같은지만 비교

그래서 서버가 뚫려도 공격자가 얻는 것은 해시뿐입니다. 원본 비밀번호가 아니에요. … 라고 하고 싶지만, 여기에 두 가지 함정이 있습니다.

직접 봅시다. 서버가 뚫려 /etc/shadow(비밀번호 해시가 든 파일)가 새어 나갔다고 상상하고, 공격자가 그것으로 무엇을 하는지 봅니다.

각 해시 맨 앞의 $1$ / $6$ / $2b$ 가 알고리즘 표시입니다.
🖥️ 내 가상 서버 브라우저 안에서 실행 (계산용)
어떤 계정이 몇 초 만에 깨지는지 보세요.
🖥️ 내 가상 서버 브라우저 안에서 실행 (계산용)
해시 실험실 — 알고리즘·솔트를 바꿔 가며 공격자가 얼마나 빨리 깨는지
불러오는 중…
🤔 확인 문제
서버 DB가 유출됐는데, 비밀번호가 솔트를 넣은 bcrypt 해시로 저장돼 있었습니다. 공격자는?
🤔 확인 문제
비밀번호 저장에 SHA-256 을 쓰면 안 되는 이유로 가장 정확한 것은?