Password 저장
한 줄 정의
Password 저장은 원문 비밀번호를 저장하지 않고, salt와 느린 단방향 해시를 사용해 유출되더라도 원문 복원을 어렵게 만드는 설계다.
실무에서 왜 문제 되는가
- 원문이나 빠른 해시로 저장하면 DB 유출 시 사용자 계정이 대량으로 탈취될 수 있다.
- 같은 비밀번호가 같은 해시로 저장되면 rainbow table이나 패턴 분석에 취약하다.
- 해시 비용 계수가 너무 낮으면 brute force에 약하고, 너무 높으면 로그인 지연과 CPU 부하가 커진다.
- 비밀번호 변경, 임시 비밀번호, 재설정 토큰도 같은 수준의 보안 기준이 필요하다.
동작 원리
- 사용자가 비밀번호를 입력한다.
- 서버는 사용자별 salt를 포함해 bcrypt, scrypt, Argon2 같은 password hashing 알고리즘으로 해시한다.
- DB에는 원문이 아니라 알고리즘 정보, 비용 계수, salt가 포함된 해시 결과만 저장한다.
- 로그인 시 입력값을 같은 방식으로 검증하고 결과만 비교한다.
- 비용 계수나 알고리즘을 바꿀 때는 재로그인 또는 비밀번호 변경 시점에 점진적으로 갱신한다.
실무 판단 기준
| 상황 | 선택 | 이유 |
|---|---|---|
| 일반 비밀번호 저장 | bcrypt, scrypt, Argon2 | brute force 비용을 높인다 |
| 단순 SHA 계열 해시 | 사용하지 않음 | 너무 빨라 대입 공격에 약하다 |
| 사용자별 salt | 필수 | 같은 비밀번호도 다른 해시가 되게 한다 |
| 비용 계수 | 운영 부하 기준으로 조정 | 보안과 로그인 성능의 균형이 필요하다 |
| 재설정 링크 | 짧은 TTL의 단회성 토큰 | 비밀번호와 동일하게 탈취 위험을 고려한다 |
자주 나는 실수
- SHA-256 같은 빠른 해시만 사용한다.
- 모든 사용자에게 같은 salt를 사용한다.
- 비밀번호를 로그, 이벤트, 예외 메시지에 남긴다.
- 임시 비밀번호를 평문으로 저장하거나 재사용 가능하게 둔다.
- 해시 비용 계수를 운영 CPU 부하와 함께 검증하지 않는다.
확인 방법
- 코드 리뷰: 비밀번호 원문이 DB, 로그, 이벤트에 남지 않는지 확인한다.
- 테스트: 같은 비밀번호라도 사용자마다 저장된 해시가 다른지 확인한다.
- 부하 테스트: 로그인 peak 상황에서 해시 비용이 CPU를 과도하게 쓰지 않는지 확인한다.
- 보안 점검: 재설정 토큰의 TTL, 단회성 사용, 실패 횟수 제한을 확인한다.
장점과 한계
| 장점 | 한계 |
|---|---|
| DB 유출 시 원문 비밀번호 복원을 어렵게 만든다 | 약한 비밀번호 자체를 막지는 못한다 |
| salt로 동일 비밀번호 패턴 노출을 줄인다 | credential stuffing은 별도 대응이 필요하다 |
| 비용 계수로 공격 비용을 높인다 | 서버 CPU 비용도 같이 증가한다 |
짧은 예제
public void changePassword(User user, String rawPassword) {
String encoded = passwordEncoder.encode(rawPassword);
user.changePassword(encoded);
}
public boolean matches(String rawPassword, User user) {
return passwordEncoder.matches(rawPassword, user.passwordHash());
}비밀번호 원문은 검증이나 변경 시점에만 메모리에 존재해야 하며, 저장소와 로그에는 남기지 않는다.
핵심 요약
비밀번호는 원문으로 저장하지 않고 password hashing 알고리즘으로 저장한다.
SHA 계열의 빠른 해시는 비밀번호 저장에 적합하지 않다.
사용자별 salt는 같은 비밀번호가 같은 해시로 보이는 문제를 줄인다.
비용 계수는 공격 비용을 높이지만 운영 서버의 CPU 비용도 증가시킨다.
비밀번호 재설정 토큰도 짧은 TTL과 단회성 사용을 보장해야 한다.
로그, 이벤트, 예외 메시지에 비밀번호 원문이 남지 않게 해야 한다.
꼬리 질문
- 비밀번호 저장에 SHA-256만 쓰면 왜 위험한가?
- salt와 비용 계수는 각각 어떤 문제를 줄이는가?
- 비밀번호 재설정 기능에서 주의할 점은 무엇인가?