Privacy & Security

비밀번호 해싱이 실제로 보호해 주는 것

Password hashing은 마법이 아닙니다. 사용자 테이블이 유출되는 날을 위한 피해 통제 장치입니다.

The Wux Webtools Team The Wux Webtools Team 13 읽기 최소 시간 AI 지원, 인간 검토
Illustration of a password being transformed into a protected hash before storage in a database.
목차
  1. 짧은 요약
  2. 비밀번호 hash란 무엇인가
  3. hashing이 보호해 주는 것
  4. 1. 데이터베이스 침해 이후 즉각적인 비밀번호 노출
  5. 2. 전체 사용자 기반을 향한 대량 공격
  6. 3. 빠른 offline 추측
  7. hashing이 보호해 주지 않는 것
  8. 1. Phishing
  9. 2. Credential stuffing
  10. 3. logs나 analytics에 캡처된 비밀번호
  11. 4. 나쁜 session 보안
  12. 5. 약한 password reset과 account recovery
  13. algorithm 선택: 지금 무엇을 사용할 것인가
  14. Cost factor는 한 번 정하고 끝나는 것이 아니다
  15. Pepper: 유용하지만 대체재는 아니다
  16. 운영 checklist
  17. 정직한 mental model

짧은 요약

비밀번호를 해싱하는 것은 비밀번호 데이터베이스가 도난당했을 때 사용자를 보호합니다.

그것이 핵심 역할입니다. 유일한 세부 사항도, 전체 보안 모델도 아니지만, 비밀번호를 직접 저장하지 않고 해싱하는 중심적인 이유입니다.

제대로 해싱된 비밀번호는 되돌리기 어렵습니다. 공격자가 사용자 테이블의 사본을 얻더라도 Alice의 비밀번호가 Spring2026!라는 사실을 즉시 알아내서는 안 됩니다. 대신 추측값과 대조해 테스트하는 데 시간, 비용, 하드웨어가 필요한 저장된 hash를 얻게 됩니다.

이 차이는 중요합니다. Password hashing은 그 자체로 login을 안전하게 만들기 위한 것이 아닙니다. phishing을 막지 못합니다. 유출된 비밀번호를 당신의 login form에 대입해 보는 시도를 막지 못합니다. login 이후의 session cookie를 보호하지도 못합니다. 이는 매우 특정한 실패, 즉 비밀번호 검증자 저장소가 노출된 이후에 시간을 벌고 피해를 줄여 줍니다.

이 경계를 이해하면 algorithm, work factor, reset, logging, incident response에 대해 더 나은 결정을 내릴 수 있습니다.

비밀번호 hash란 무엇인가

비밀번호 hash는 비밀번호에 단방향 함수를 적용한 출력값이며, 보통 고유한 salt와 의도적으로 느린 password-hashing algorithm을 함께 사용합니다.

사용자가 계정을 만들 때 시스템은 대략 다음과 같이 동작해야 합니다.

  1. HTTPS를 통해 비밀번호를 받습니다.
  2. 무작위의 고유한 salt를 생성합니다.
  3. 비밀번호와 salt를 Argon2id, bcrypt, scrypt, PBKDF2 같은 password-hashing function에 통과시킵니다.
  4. algorithm 이름, parameters, salt, 결과 hash를 저장합니다.
  5. 원래 비밀번호는 폐기합니다.

나중에 사용자가 login하면 시스템은 제출된 비밀번호와 저장된 parameters로 동일한 hashing 과정을 반복합니다. 결과 hash가 저장된 hash와 일치하면 login이 성공합니다.

중요한 점은 application이 원래 비밀번호를 알 필요가 없다는 것입니다. 제출된 비밀번호가 기대한 결과를 만들어 내는지만 검증하면 됩니다.

이것이 비밀번호를 reversible encryption으로 저장하는 방식이 보통 잘못된 모델인 이유입니다. application이 모든 비밀번호를 복호화할 수 있다면, decryption key를 훔친 누구든 같은 일을 할 수 있습니다. 비밀번호는 일반적으로 단순히 숨겨지는 것이 아니라, 역방향으로 검증 불가능해야 합니다.

hashing이 보호해 주는 것

1. 데이터베이스 침해 이후 즉각적인 비밀번호 노출

공격자가 plaintext 비밀번호가 들어 있는 데이터베이스를 훔치면 피해는 즉시 발생합니다. 모든 비밀번호가 노출됩니다. 사용자는 당신의 사이트뿐 아니라 그 비밀번호를 재사용한 모든 곳에서 위험해집니다.

데이터베이스에 잘 해싱된 비밀번호가 들어 있다면 공격자는 더 많은 작업을 해야 합니다. 후보 비밀번호를 추측하고, 각 추측값을 올바른 salt와 parameters로 해싱한 다음, 결과를 비교해야 합니다.

약한 비밀번호라면 여전히 빠를 수 있습니다. 강하고 고유한 비밀번호라면 현실적으로 어려울 수 있습니다.

Hashing은 치명적인 노출을 경주로 바꿉니다. 공격자가 많은 비밀번호를 깨기 전에 사용자가 비밀번호를 reset할 수 있고, 당신이 incident를 억제할 수 있는가?

완벽하지는 않습니다. 여전히 침해입니다. 하지만 훨씬 더 나은 실패 모드입니다.

2. 전체 사용자 기반을 향한 대량 공격

Salt는 공격자가 precomputed table로 많은 사용자를 효율적으로 공격하지 못하게 하기 때문에 비밀번호 저장에서 핵심적인 부분입니다.

Salt는 secret이 아닙니다. hash와 함께 저장됩니다. 그 역할은 고유성입니다.

두 사용자가 같은 비밀번호를 선택하더라도 고유한 salt는 저장된 hash가 서로 달라지도록 합니다. 이를 통해 공격자는 많은 사용자가 같은 비밀번호를 공유한다는 사실을 한눈에 알 수 없습니다. 또한 password-to-hash mapping의 거대한 precomputed list를 사용하는 고전적인 rainbow table 공격도 막습니다.

Salt가 없으면 하나의 깨진 hash가 같은 비밀번호를 가진 모든 사용자를 드러낼 수 있습니다. Salt가 있으면 각 비밀번호 추측값을 각 사용자별로 따로 테스트해야 합니다.

3. 빠른 offline 추측

공격자가 비밀번호 데이터베이스를 손에 넣으면 offline으로 추측할 수 있습니다. 이는 login rate limit, CAPTCHA, IP blocking, monitoring이 더 이상 의미가 없다는 뜻입니다. 공격자는 자신의 하드웨어에서 추측값을 테스트할 수 있습니다.

여기서 algorithm 선택이 중요해집니다.

SHA-256, SHA-512 같은 general-purpose hash는 빠르도록 설계되었습니다. 이는 file integrity와 digital signature에는 좋습니다. 비밀번호 저장에는 나쁩니다.

Password-hashing algorithm은 느리고, 조정 가능하며, 때로는 memory-hard하도록 설계되었습니다. Argon2id, bcrypt, scrypt, PBKDF2는 모두 각 추측에 의미 있는 시간이 걸리도록 cost parameters를 조정할 수 있게 해 줍니다.

Argon2id는 CPU 시간과 memory를 모두 요구하도록 구성할 수 있어 대규모 GPU cracking을 더 비싸게 만들기 때문에 새로운 시스템에 널리 권장됩니다. bcrypt는 password length handling 같은 한계가 있지만, 잘 구성되어 있다면 여전히 흔하고 수용 가능한 선택입니다. PBKDF2는 특히 FIPS-validated components가 필요한 일부 compliance-driven 환경에서 여전히 사용됩니다.

원칙은 단순합니다. 정상적인 login은 충분히 빠르게 유지하되, 수십억 번의 추측은 비싸게 만드는 것입니다.

hashing이 보호해 주지 않는 것

1. Phishing

사용자가 가짜 login page에 비밀번호를 입력하면, 당신의 server에서 수행하는 hashing은 도움이 되지 않습니다. 공격자는 당신의 시스템이 비밀번호를 보기 전에 이미 비밀번호를 받습니다.

여기서의 방어책은 다릅니다. multi-factor authentication, passkeys, user education, domain hygiene, phishing-resistant authentication, 신중한 password reset flow가 필요합니다.

Password hashing은 저장된 secret을 위한 backstop입니다. 사용자가 속아서 그 secret을 넘겨주는 상황에 대한 방어책은 아닙니다.

2. Credential stuffing

Credential stuffing은 공격자가 한 service에서 유출된 username과 password 쌍을 가져와 다른 service에 시도할 때 발생합니다.

당신의 password hash가 훌륭하더라도, 사용자가 비밀번호를 재사용한다면 credential stuffing은 여전히 성공할 수 있습니다.

이는 데이터베이스를 향한 offline 공격이 아니라 login form을 향한 online 공격입니다. rate limiting, anomaly detection, breached-password checks, MFA, 그리고 쉬운 denial-of-service 기회를 만들지 않는 합리적인 lockout policies가 필요합니다.

같은 실용적인 사고는 노출된 모든 form에도 적용됩니다. authentication surface를 검토하고 있다면 your contact form is your biggest spam liability를 읽어 볼 가치가 있습니다. mechanics는 다르지만 교훈은 비슷합니다. public inputs에는 깨끗한 backend code만이 아니라 abuse controls가 필요합니다.

3. logs나 analytics에 캡처된 비밀번호

Hashing은 plaintext 비밀번호가 빠르게 폐기되고 다른 곳에 복사되지 않을 때에만 도움이 됩니다.

흔한 실패 사례는 다음과 같습니다.

  • 실패한 login 시도에서 전체 request body를 logging합니다.
  • 비밀번호를 error monitoring tools로 보냅니다.
  • session replay products에서 password fields를 캡처합니다.
  • 잘못 설계된 reset 또는 migration flow 중 URLs에 credentials를 포함합니다.
  • import 중 임시 plaintext 비밀번호를 저장합니다.

이런 실수는 password hashing을 완전히 우회합니다. plaintext가 logs, backups, data warehouses, third-party tools에 남는다면 hash function은 무의미합니다.

비밀번호 field를 toxic data로 취급하세요. logging하기 전에 redaction하세요. analytics에서 제외하세요. URLs에 넣지 마세요. production traces에 접근할 수 있는 사람을 제한하세요.

4. 나쁜 session 보안

login 이후 사용자의 browser는 보통 session cookie나 token을 받습니다. 그 token이 도난당하면 공격자는 비밀번호가 전혀 필요 없을 수 있습니다.

Password hashing은 cross-site scripting, insecure cookies, session fixation, 약한 token generation, 지나치게 긴 session lifetime을 막지 못합니다.

Session cookie는 별도의 검토가 필요합니다. HttpOnly, Secure, 적절한 SameSite, high-risk session의 짧은 lifetime, password 변경 시 server-side invalidation이 필요합니다. 더 넓은 privacy와 browser 환경도 계속 변하고 있으며, 이는 what changed for cookies in 2026에서 다룬 바 있습니다.

5. 약한 password reset과 account recovery

많은 account takeover는 비밀번호에서 시작하지 않습니다. reset flow에서 시작합니다.

reset token이 예측 가능하거나, 오래 지속되거나, referrer header를 통해 유출되거나, 침해된 email account로 전송된다면 password hashing은 당신을 구해 주지 못합니다.

High-entropy reset token, 짧은 expiry window, one-time use, 명확한 user notification을 사용하세요. email이 recovery channel인 경우가 많기 때문에 기본적인 domain authentication도 중요합니다. 팀이 DNS records를 신비로운 의식처럼 다룬다면 a developer-friendly tour of MX, SPF, DKIM and DMARC부터 시작하세요.

algorithm 선택: 지금 무엇을 사용할 것인가

새 application에는 platform이 잘 지원한다면 Argon2id를 사용하세요. 이는 Password Hashing Competition의 우승작이며, GPU-heavy cracking에 대한 저항을 포함해 비밀번호 저장을 위해 설계되었습니다.

합리적인 현대적 우선순위는 다음과 같습니다.

  1. 사용할 수 있는 새로운 시스템에는 Argon2id.
  2. Argon2id가 실용적이지 않고 bcrypt support가 성숙한 경우 bcrypt.
  3. memory-hard configuration이 잘 지원되는 경우 scrypt.
  4. platform 또는 compliance constraints 때문에 필요한 경우 PBKDF2.

plain SHA-256, SHA-512, MD5 또는 sha256(password + salt) 같은 자체 조합은 피하세요. Fast hash는 password storage function이 아닙니다. 영리해 보이는 custom construction은 지루한 표준 방식보다 대체로 더 나쁩니다.

또한 algorithm trivia를 중심으로 자신만의 password policy를 발명하지 마세요. 12가지 규칙으로 된 password composition checklist가 사용자를 예측 가능한 패턴으로 몰아간다면 사용자에게 도움이 되지 않습니다. 더 길고 고유한 비밀번호, password managers, breached-password screening, MFA가 보통 더 중요합니다.

Cost factor는 한 번 정하고 끝나는 것이 아니다

Password hashing에는 parameters가 있습니다. Argon2id에는 memory, iterations, parallelism이 있습니다. bcrypt에는 cost factor가 있습니다. PBKDF2에는 iteration count가 있습니다.

이 값들은 production environment를 기준으로 선택해야 합니다. 너무 낮으면 공격자가 싸게 추측합니다. 너무 높으면 login system이 느려지거나 denial-of-service에 취약해집니다.

실용적인 목표는 실제 server에서 password verification 하나당 수십에서 수백 밀리초 범위인 경우가 많으며, traffic과 risk에 따라 달라집니다. High-security system은 더 높은 값을 선택할 수 있습니다. Consumer-scale system은 신중한 capacity planning이 필요할 수 있습니다.

5년 전 blog post에서 cost factor를 복사하지 마세요. Hardware는 변합니다. Libraries도 변합니다. Traffic도 변합니다.

Parameters를 주기적으로 검토하고 rehashing을 계획하세요. 일반적인 패턴은 각 hash와 함께 algorithm과 parameters를 저장하는 것입니다. 성공적인 login 시 저장된 parameters가 오래되었다면 제출된 비밀번호를 더 새로운 configuration으로 rehash하고 record를 업데이트합니다.

Pepper: 유용하지만 대체재는 아니다

Pepper는 password-hashing process에 추가되는 secret value이며, 보통 secrets manager나 hardware security module에 데이터베이스와 별도로 저장됩니다.

Salt와 달리 pepper는 반드시 secret으로 유지되어야 합니다.

Pepper는 데이터베이스가 유출되었지만 application secrets는 유출되지 않았을 때 피해를 줄일 수 있습니다. 좋은 key management를 갖춘 성숙한 환경에서 가장 유용합니다. 같은 공격자가 데이터베이스와 application configuration을 모두 훔칠 수 있다면 덜 유용합니다.

Pepper를 사용한다면 rotation을 신중히 계획하세요. 설계에 따라 rotation은 사용자가 다시 login하거나 password를 reset해야 할 수 있습니다. Pepper는 추가 layer이지, 기본 hash settings를 약화할 이유가 아닙니다.

운영 checklist

실제 시스템을 책임지고 있다면 실용적인 checklist는 짧습니다.

  • 비밀번호는 표준 password-hashing algorithm으로만 저장합니다.
  • 비밀번호마다 고유한 random salt를 사용합니다.
  • 새로운 build에는 Argon2id를 우선합니다.
  • production-like hardware에서 cost parameters를 조정합니다.
  • 각 hash와 함께 algorithm과 parameters를 저장합니다.
  • parameters가 오래되면 login 시 rehash합니다.
  • 비밀번호를 절대 logging하거나 analytics tools로 보내지 않습니다.
  • credentials가 제출되는 모든 곳에 TLS를 사용합니다.
  • risk가 정당화되는 곳에는 MFA 또는 passkeys를 추가합니다.
  • reset flow를 login flow만큼 진지하게 보호합니다.
  • forced reset과 user notification을 위한 incident plan을 갖춥니다.

Password hashing은 화려하지 않습니다. 배관에 가깝습니다. 하지만 침해가 고통스러운 incident로 끝날지, 전체 사용자 재난으로 번질지를 결정하는 종류의 배관입니다.

<!-- tool-cta:start -->

💡 시도해 보세요: Hash Generator로 동일한 입력이 서로 다른 알고리즘에 어떻게 매핑되는지 확인하고, 빠른 해시와 비밀번호 등급 해시의 차이를 구체적으로 이해해 보세요.

<!-- tool-cta:end -->

정직한 mental model

Password hashing을 이해하는 가장 좋은 방식은 다음과 같습니다.

Hashing은 사용자가 비밀번호를 입력하는 동안 그 비밀번호를 보호하지 않습니다. 사용자가 login한 뒤 account를 보호하지 않습니다. 웹 전반에서 비밀번호를 재사용하는 사용자를 보호하지 않습니다.

저장된 verifier를 보호합니다.

좁게 들리지만 매우 중요합니다. Databases는 유출됩니다. Backups도 유출됩니다. Staging systems는 복사됩니다. Vendors는 가져서는 안 되는 access를 얻습니다. 오래된 exports는 누구도 기억하지 못할 만큼 오래 object storage에 남아 있습니다.

그 일이 발생했을 때, password storage design은 공격자가 비밀번호를 받는지, 아니면 비용이 많이 드는 추측 문제를 받는지를 가르는 차이가 됩니다.

그것이 비밀번호 hashing이 실제로 보호해 주는 것입니다.

자주 묻는 질문

Salt를 추가하면 SHA-256으로도 비밀번호 저장에 충분한가요?
아니요. Salt는 필요하지만 SHA-256은 여전히 너무 빠릅니다. 비밀번호 저장에는 Argon2id, bcrypt, scrypt, PBKDF2 같은 느리고 조정 가능한 function이 필요합니다.
비밀번호는 hashing 대신 encryption해야 하나요?
보통은 아닙니다. Encryption은 되돌릴 수 있으므로 도난당한 key가 모든 비밀번호를 노출할 수 있습니다. 비밀번호는 일반적으로 되돌릴 수 없는 hash로 저장해야 합니다.
Salt와 pepper의 차이는 무엇인가요?
Salt는 각 password hash와 함께 저장되는 고유한 non-secret value입니다. Pepper는 데이터베이스와 별도로 저장되는 shared secret입니다. Salt는 필수이고, pepper는 선택 사항이며 운영상 더 복잡합니다.
Password hashing이 credential stuffing을 막아 주나요?
아니요. Credential stuffing은 다른 service에서 유출된 비밀번호를 사용하는 online 공격입니다. 그 risk를 줄이려면 rate limiting, breached-password checks, MFA, monitoring이 필요합니다.
오래된 비밀번호를 rehash해야 하나요?
대개 그렇습니다. 각 password record와 함께 hash parameters를 저장한 다음, algorithm이나 cost settings가 오래되었을 때 성공적인 login 이후 rehash하세요.

출처 및 추가 읽기

  1. OWASP Password Storage Cheat Sheet
  2. NIST Special Publication 800-63B: Digital Identity Guidelines
  3. RFC 9106: Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications
  4. Have I Been Pwned: Pwned Passwords
저자에 대하여
The Wux Webtools Team

마지막 업데이트:

계속 읽기