일반 암호학적 해시는 입력을 빠르게 digest로 바꾸므로, 비밀번호 파일이 탈취되면 공격자가 후보를 매우 빠르게 반복 확인할 수 있습니다. 비밀번호 저장에는 salt와 비용 인자를 받는 적절한 password hashing scheme을 사용해 각 추측의 비용을 높여야 합니다.
NIST SP 800-63B-4 최종판은 salt와 결과 해시를 각 비밀번호마다 저장하도록 SHALL로 요구합니다. 해시 방식과 비용 인자 참조는 이행을 위해 저장하도록 SHOULD로 권고하며, 비용 인자는 검증기 성능에 악영향을 주지 않는 현실적인 범위에서 높이도록 SHOULD로 안내합니다. salt는 비밀키가 아니며 scrypt는 하나의 KDF 사례입니다.
빠른 digest는 비밀번호 후보를 빨리 시험하게 합니다
일반 해시 함수는 입력을 digest로 바꾸며, 검증자는 같은 입력을 다시 계산해 저장값과 비교할 수 있습니다. 비밀번호는 사용자가 고르는 값이라 후보를 추측할 수 있습니다. 데이터베이스가 노출되면 공격자는 후보를 해시해 저장 결과와 대조하는 오프라인 추측을 합니다. 빠른 범용 해시를 그대로 쓰면 후보를 반복 시험하는 비용이 낮습니다. 해시 길이를 늘리거나 비밀번호를 여러 번 이어 붙이는 것만으로 적절한 저장 방식이 되지는 않습니다.
| 구성 | 역할 | 기억할 점 |
|---|---|---|
| salt | 각 저장 항목의 계산 입력을 달리함 | 비밀이 아니며 저장된 해시와 함께 보관 가능 |
| 비밀번호 해시 방식 | 비밀번호·salt·비용 인자로 verifier 생성 | 후보 하나마다 계산 비용을 들게 함 |
| 비용 인자·방식 버전 | 검증에 쓴 설정을 다시 알리고 이행을 지원 | 환경이 바뀌면 조정·마이그레이션 검토 |
추상 단위로 후보 시험 비용을 비교합니다
새로 만든 산술 예입니다. 실제 벤치마크가 아니라, 범용 해시의 후보당 상대 비용을 1단위, 비용 인자가 있는 방식의 비용을 1,000단위라고 둡니다. 후보가 1,000,000개라면 첫 방식은 1,000,000×1=1,000,000단위이고 두 번째는 1,000,000×1,000=1,000,000,000단위입니다. 반올림 전 결과는 정확히 1,000,000과 1,000,000,000이며, 단순 모형에서 총 계산량은 1,000배입니다. 이 숫자는 실제 실행 시간이나 공격 성공 가능성이 아닙니다.
현실에서는 공격 장비의 병렬성, CPU·메모리, 구현, 매개변수와 후보 순서가 결과에 영향을 줍니다. 따라서 이 예로 특정 서비스가 몇 초나 몇 년 동안 안전하다고 추론해서는 안 됩니다. 이 계산은 비용이 후보마다 반복된다는 점만 보여 줍니다.
salt와 KDF는 서로 다른 일을 합니다
salt는 일반적으로 저장 항목마다 고유하게 만들어 해시 계산에 넣는 값입니다. 같은 비밀번호를 쓰는 두 계정이 같은 결과를 그대로 공유하지 않게 하고, 공격자가 미리 계산한 표를 여러 계정에 재사용하기 어렵게 합니다. salt 자체가 비밀일 필요는 없으며 비밀번호 해시와 함께 저장됩니다. salt만 추가하고 빠른 계산을 유지하면 후보를 많이 시험할 수 있다는 문제는 남습니다. 따라서 salt는 비용이 큰 비밀번호 해시 방식과 함께 사용해야 합니다.
NIST SP 800-63B-4 §3.1.1.2는 verifier가 비밀번호를 오프라인 공격에 견디는 형태로 저장하도록 요구합니다. 적절한 password hashing scheme은 비밀번호·salt·비용 인자를 받아 각 추측의 비용을 높입니다. 이 문서는 salt를 최소 32비트로 하고 충돌 가능성을 줄이라고 하며, 각 비밀번호의 salt 값과 결과 해시는 SHALL로 저장하도록 요구합니다. 이와 달리 사용한 방식과 비용 인자에 대한 참조는 새 알고리즘이나 작업 비용으로 옮길 수 있도록 저장할 것을 SHOULD로 권고합니다. 비용 인자도 verifier 성능에 악영향을 주지 않는 현실적인 범위에서 최대한 높이고 계산 성능이 향상되면 올리도록 SHOULD로 안내합니다. SHALL과 SHOULD는 같은 강도의 문구가 아닙니다.
RFC 7914는 scrypt라는 비밀번호 기반 키 유도 함수를 정의합니다. 메모리 집약 특성은 맞춤형 하드웨어의 이점을 줄이는 데 목적이 있습니다. 문서는 salt와 비용 매개변수 N, 블록 크기 r, 병렬화 값 p를 설명합니다. 이 RFC는 Informational이며 Internet Standards Track 규격이 아닙니다. 2016년 예시를 모든 현재 시스템의 최선 알고리즘이나 값으로 읽지 말고, 실제 설정은 공식 지침과 환경 시험으로 정해야 합니다.
- 저장값이 일반 해시인지, 비밀번호 전용 해시 방식인지 확인합니다.
- NIST 요구의 SHALL 항목인 salt와 결과 해시가 각 비밀번호마다 저장되는지 확인합니다.
- 방식과 비용 인자 참조 저장은 SHOULD 권고임을 구분하고, 추후 알고리즘과 비용을 이행할 수 있도록 기록합니다.
- 비용을 올릴 때에는 검증기 성능에 악영향을 주지 않는 범위에서 지연과 자원 사용을 측정합니다.
- 시간이 지나면 계산 성능과 지침이 달라질 수 있으므로 사용 중인 설정을 재평가하고 단계적으로 이행합니다.
흔한 오해는 salt를 숨기면 비밀번호가 보호된다고 생각하는 것입니다. salt는 보통 공개해도 되는 값이고, 비밀성을 담당하는 것은 비밀번호나 별도로 관리하는 서버 비밀키입니다. NIST는 verifier가 별도의 비밀키를 이용한 추가 keyed hashing 또는 암호 연산을 수행하는 방안도 설명하지만, 그 키는 해시 저장소와 분리해 보호해야 한다고 합니다. 이는 salt를 비밀키처럼 다루라는 뜻이 아닙니다. 비밀번호 저장은 저장 해시의 비용, 별도 키 보호, 온라인 인증 시도 제한 등 여러 방어가 함께 작동하는 문제입니다.
회상 연습: salt만 넣은 빠른 해시를 평가합니다
교육용 문제입니다. 두 계정이 우연히 같은 비밀번호를 선택했고, 저장 방식이 계정마다 다른 salt를 넣은 빠른 일반 해시뿐이라고 합시다. salt는 어떤 반복 공격의 재사용을 어렵게 하나요? 그런데 오프라인에서 후보 하나를 확인하는 계산 자체는 왜 여전히 빠를 수 있나요? 후보 1,000,000개, 후보당 추상 비용 1,000단위라면 전체 추상 비용은 얼마인가요? NIST SP 800-63B-4에서 각 비밀번호의 salt와 결과 해시 저장은 SHALL 요구인가요, SHOULD 권고인가요? 방식과 비용 인자 참조는 어느 쪽인가요?
계정별 salt는 같은 비밀번호를 쓰는 계정의 저장 결과를 다르게 하고, 한 번 만든 후보 표를 여러 계정에 그대로 적용하는 것을 어렵게 합니다. 하지만 빠른 일반 해시라면 공격자가 각 salt에 맞춰 후보를 계산하는 작업은 여전히 빠를 수 있으므로 비용이 큰 비밀번호 해시 방식이 필요합니다. 추상 총 비용은 1,000,000×1,000=1,000,000,000단위입니다. NIST 문서에서는 salt와 결과 해시를 각 비밀번호마다 저장하는 것이 SHALL 요구이고, 해시 방식과 비용 인자 참조 저장은 이행을 돕는 SHOULD 권고입니다. 이 곱셈은 설명용이며 실제 시간이나 권장 매개변수는 아닙니다.
정답을 가리고 확인해 보세요
이 글을 위해 만든 학습 예시이며 공식 기출문제나 판매 카드의 인용이 아닙니다.
NIST SP 800-63B-4 §3.1.1.2에서 비밀번호마다 SHALL로 저장해야 하는 두 값은 무엇이며, 해시 방식과 비용 인자 참조는 어떤 강도의 문구로 저장을 권고하는가?
정답과 해설 확인
각 비밀번호의 salt 값과 결과 해시는 SHALL로 저장해야 합니다. 사용한 password hashing scheme과 비용 인자를 가리키는 참조는 알고리즘과 작업 비용의 이행을 위해 저장하도록 SHOULD로 권고합니다.NIST는 salt와 resulting hash의 저장을 요구사항으로 두고, scheme과 cost factor에 대한 reference의 저장은 이행을 돕는 권고로 구분합니다. 비용 인자는 verifier 성능에 부정적 영향을 주지 않는 한 최대한 높이고 시간이 지나면 늘리도록 SHOULD로 안내합니다. SHALL과 SHOULD를 같은 강도로 읽으면 안 됩니다.