콘텐츠로 이동

BCrypt vs SHA-256 — 같은 해시인데 왜 다른 알고리즘?

한 줄 요약: 비밀번호는 사용자가 만든 약한 입력 — 의도적으로 느린 BCrypt 로 brute force 차단. Refresh token 은 서버가 만든 강한 입력 (256-bit random) — brute force 불가능하니 빠른 SHA-256 으로 충분.

차이 표

비교 항목 비밀번호 (BCrypt) Refresh Token (SHA-256)
누가 만드나 사용자 직접 서버
입력 강도 약함 (abcd1234, password!, 사전 단어) 매우 강함 (32바이트 secure random, 2^256 가지)
Brute force 위험 큼 (사전 공격 / rainbow table) 사실상 0 (우주 종말까지 못 풀음)
알고리즘 속도 느림 (cost 10 ≈ 0.1초) — 의도적 빠름 (μs 단위)
느림의 효과 공격자가 1초에 수십억 번 시도 못 함 의미 없음 — 입력 자체가 이미 강해서

핵심 원리

약한 입력에는 느린 해시로 시간을 늘리고, 강한 입력에는 빠른 해시로 성능을 챙긴다.

BCrypt 의 cost factor

new BCryptPasswordEncoder(10);  // cost = 10
  • cost 10 = 2^10 = 1024번 내부 반복 → 검증 1회에 약 0.1초
  • 공격자가 1초당 10번밖에 시도 못 함 → 1억 개 비밀번호 사전 공격에 약 116일 필요
  • cost 를 12로 올리면 4배 느려짐 → 검증 0.4초 / 공격 비용 4배

Cost 선택 기준

  • 너무 낮으면 (cost 4) — 검증 빠르지만 공격도 빠름
  • 너무 높으면 (cost 14) — 검증 1초 이상, 로그인 응답 느려져 UX 폭망
  • 권장: cost 10-12 — 검증 0.1-0.5초, 균형점

SHA-256 은 왜 빠른가

  • 입력 → 단순 비트 연산 + 라운드 64번 — 마이크로초 (μs) 단위
  • 의도적 지연 없음 — 검증 / 비교는 빠를수록 좋음

Refresh token 입력의 강도

32바이트 secure random = 2^256 가지 = 약 1.16 × 10^77 가지
  • 우주의 원자 수 (10^80) 와 비슷한 규모
  • Brute force 시도 자체가 수학적으로 불가능

그럼 비밀번호도 그냥 강하게 만들면 SHA-256 쓸 수 있나?

이론상 — 32바이트 secure random 같은 비밀번호를 강제하면 SHA-256 한 번이 안전.

실제로 안 되는 이유: - 사용자가 외울 수 없음 → password manager 의존 - 입력 시 부담 - 사람이 만드는 비밀번호는 절대 32바이트 random 못 됨 — 패턴 / 어휘 / 익숙한 변환 (p@ssw0rd) - 그래서 BCrypt 같은 느린 알고리즘이 현실적 방어선

발표 시 한 줄

"비밀번호 같은 약한 입력은 검증 자체를 느리게 만들어서 공격을 막고, 서버가 만든 강한 입력은 검증을 빠르게 해도 안전합니다."

FAQ

Q: PBKDF2 / scrypt / Argon2 는 뭔가요? → BCrypt 와 같은 카테고리의 "느린 해시" 함수들. 메모리 사용량을 늘리거나 (scrypt), GPU/ASIC 공격까지 막거나 (Argon2) 하는 변형. 현재 표준 권장은 Argon2id. BCrypt 는 여전히 안전하고 널리 사용됨.

Q: 왜 SHA-256 으로 비밀번호 안 하나? → SHA-256 은 너무 빠름. 공격자가 1초에 수십억 번 시도 가능. 사전 공격에 무력.

관련