비밀번호 해싱 원리 완벽 정리 - 사이트도 내 비밀번호를 모르는 이유와 안전한 저장의 비밀
회원가입한 사이트는 내 비밀번호를 그대로 저장할까요? 해시 함수와 솔트, bcrypt까지 비밀번호가 안전하게 보관되는 원리를 쉬운 예시로 풀어드립니다. 유출 사고에서 계정을 지키는 실전 수칙도 함께 확인하세요.
![]()
회원가입을 하다가 문득 이런 생각이 든 적 있으실 겁니다. 이 사이트가 내 비밀번호를 그대로 저장해두는 건 아닐까. 실제로 뉴스에서 개인정보 유출 사고를 접할 때마다 불안해지는 것도 사실입니다. 그런데 제대로 만들어진 서비스라면 운영자조차 여러분의 비밀번호를 알 수 없습니다. 그 비밀이 바로 비밀번호 해싱 원리에 있습니다.
비밀번호 해싱이란 무엇인가
해싱은 임의의 데이터를 정해진 길이의 문자열로 바꾸는 계산 과정입니다. 이때 사용하는 함수를 해시 함수라고 부릅니다. 예를 들어 SHA-256이라는 해시 함수에 숫자 1234를 넣으면 다음과 같은 64자리 문자열이 나옵니다.
1234 → 03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4
여기서 놀라운 점이 있습니다. 입력을 딱 한 글자만 바꿔 1235를 넣으면 결과가 완전히 달라집니다.
1235 → 310ced37200b1a0dae25edb263fe52c491f6e467268acab0ffec06666e2ed959
이렇게 입력이 조금만 달라져도 출력이 전혀 다르게 바뀌는 성질을 눈사태 효과라고 합니다. 해시 함수의 핵심 성질은 세 가지입니다.
- 일방향성: 해시 값에서 원래 비밀번호를 역으로 계산할 수 없습니다
- 결정성: 같은 입력은 언제나 같은 해시 값을 만듭니다
- 충돌 저항성: 서로 다른 두 입력이 같은 해시 값을 갖도록 만들기가 극히 어렵습니다
서비스는 회원가입 때 비밀번호 자체가 아니라 이 해시 값만 저장합니다. 로그인할 때는 입력받은 비밀번호를 다시 해싱해서 저장된 값과 비교합니다. 값이 같으면 본인이 맞다고 판단하는 것입니다. 원본 비밀번호는 어디에도 남지 않습니다.
암호화와 해싱은 어떻게 다른가
많은 분들이 해싱을 암호화의 한 종류로 알고 계시지만, 둘은 목적 자체가 다릅니다. 암호화는 키만 있으면 원래 데이터로 되돌리는 복호화가 가능합니다. 반면 해싱은 애초에 되돌리는 것이 불가능하도록 설계되어 있습니다.
| 구분 | 암호화 | 해싱 |
|---|---|---|
| 복원 가능 여부 | 키가 있으면 복호화 가능 | 불가능 (일방향) |
| 출력 길이 | 입력에 따라 달라짐 | 항상 고정 길이 |
| 주요 용도 | 메시지 전송, 파일 보호 | 비밀번호 저장, 무결성 검증 |
| 대표 기술 | AES, RSA | SHA-256, bcrypt, Argon2 |
비밀번호 저장에 암호화를 쓰면 어떻게 될까요. 복호화 키가 유출되는 순간 모든 회원의 비밀번호가 한꺼번에 노출됩니다. 그래서 비밀번호는 반드시 해싱으로 저장하는 것이 표준입니다.
비밀번호 찾기를 눌렀을 때 기존 비밀번호를 그대로 알려주는 사이트가 있다면 주의해야 합니다. 원본을 알려줄 수 있다는 것은 해싱이 아니라 평문이나 복호화 가능한 방식으로 저장하고 있다는 뜻이기 때문입니다. 제대로 된 서비스는 재설정 링크만 보내줍니다.
솔트와 레인보우 테이블 공격
해싱만으로는 충분하지 않습니다. 같은 입력은 항상 같은 해시 값을 만들기 때문입니다. 공격자들은 자주 쓰이는 비밀번호 수억 개를 미리 해싱해서 거대한 대조표를 만들어 둡니다. 이것이 레인보우 테이블입니다. 유출된 해시 값을 이 표에서 찾기만 하면 원본 비밀번호가 드러납니다.
이를 막는 장치가 솔트(salt)입니다. 솔트는 사용자마다 다르게 생성하는 무작위 문자열로, 비밀번호에 붙여서 함께 해싱합니다. 예를 들어 두 사람이 똑같이 password123을 쓰더라도 솔트가 다르면 저장되는 해시 값은 완전히 달라집니다.
- 미리 만들어 둔 레인보우 테이블이 무용지물이 됩니다
- 같은 비밀번호를 쓰는 사용자끼리도 해시 값이 달라 동시 노출을 막습니다
- 공격자는 계정 하나하나를 개별적으로 공격해야 하므로 비용이 급증합니다
bcrypt와 Argon2, 일부러 느리게 만든 해시
SHA-256 같은 범용 해시 함수는 빠른 것이 장점이지만, 비밀번호 저장에서는 그 속도가 오히려 약점이 됩니다. 최신 고성능 GPU는 MD5 해시를 초당 1천억 번 이상 계산할 수 있습니다. 8자리 정도의 단순한 비밀번호라면 무차별 대입으로 뚫리는 것은 시간 문제입니다.
그래서 비밀번호 전용 해시 함수는 일부러 느리게 설계됩니다. 대표적인 것이 1999년에 나온 bcrypt와 2015년 국제 비밀번호 해싱 공모전에서 우승한 Argon2입니다.
비용 계수라는 안전장치
bcrypt에는 비용 계수(cost factor)라는 설정이 있어 계산 횟수를 조절할 수 있습니다. 값을 1 올릴 때마다 계산량이 2배가 됩니다. 하드웨어가 빨라지면 비용 계수를 올려서 안전 수준을 유지하는 방식입니다. 같은 GPU로도 bcrypt는 초당 수십만 번 수준밖에 계산하지 못합니다. SHA 계열과 비교하면 공격 속도가 수십만 배 이상 느려지는 셈입니다.
메모리까지 요구하는 Argon2
Argon2는 여기서 한 발 더 나아가 계산할 때 일정량의 메모리를 강제로 사용하게 만듭니다. GPU는 코어당 쓸 수 있는 메모리가 제한적이어서 병렬 공격의 효율이 크게 떨어집니다. 현재 새로 시스템을 만든다면 Argon2가 가장 권장되는 선택지입니다.
사용자가 지켜야 할 실전 보안 수칙
여기까지 읽으셨다면 한 가지 중요한 결론에 도달합니다. 아무리 서버가 해싱을 잘해도 비밀번호 자체가 약하면 소용이 없다는 점입니다. 해시는 유출을 막는 기술이 아니라 유출 이후의 피해를 줄이는 기술이기 때문입니다.
사이트마다 같은 비밀번호를 쓰는 습관이 특히 위험합니다. 보안이 허술한 사이트 한 곳에서 비밀번호가 풀리면, 공격자는 그 조합으로 다른 사이트 로그인을 시도합니다. 이것이 크리덴셜 스터핑 공격이며 실제 계정 탈취 사고의 상당수가 이 방식으로 일어납니다.
한 가지 더 조심할 것이 있습니다. 요즘은 브라우저에서 바로 쓰는 온라인 도구가 많아졌습니다. QR코드 생성기나 D-Day 계산기처럼 민감한 정보를 다루지 않는 유틸리티는 부담 없이 써도 되지만, 실제 사용 중인 비밀번호를 온라인 해시 변환 사이트나 강도 측정 사이트에 입력하는 것은 피해야 합니다. 입력값이 서버로 전송되어 기록될 가능성을 배제할 수 없기 때문입니다.
지금 바로 할 수 있는 행동 두 가지를 제안합니다. 첫째, 금융과 이메일 계정부터 사이트별로 서로 다른 비밀번호를 쓰도록 비밀번호 관리자를 도입해 보세요. 둘째, 주요 계정에 2단계 인증을 켜두세요. 해시가 뚫리는 최악의 상황에서도 계정을 지키는 마지막 방어선이 됩니다.