팀 위키에 바로 붙여넣어 쓸 수 있는 Markdown 문서 버전 입니다.
🔐 비밀번호 해시 가이드 (2025)
팀 서비스 보안을 위한 비밀번호 해싱 알고리즘 및 파라미터 권장안입니다.
1. 현재 권장 알고리즘
- 기본 권장: Argon2id (PHC 우승, RFC 9106 표준)
- 대안: bcrypt (여전히 안전하지만 72바이트 길이 제한 있음)
- 금지: SHA-256/MD5 단독 사용 (빠른 해시는 레인보우 테이블에 취약)
2. Salt & Pepper
- Salt
- 사용자별 랜덤(≥16바이트)
- 해시와 함께 DB에 저장
- 목적: 레인보우 테이블 무력화
- Pepper
- 서비스 전역 비밀 키
- HSM/환경 변수에 보관
- DB 유출 시 추가 방어
3. Argon2id 파라미터 캘리브레이션
목표: 해시 1회당 100~250ms 지연
방법: m(메모리)을 먼저 올리고, t(반복횟수)로 미세조정, p는 CPU 코어 상황에 맞춰 설정.
일반 서버 (8코어, 중간 RAM)
목표 지연 m (MiB) t p 비고
| ~100ms | 96–128 | 2 | 4 | 기본 수준 |
| ~200ms | 128–192 | 3 | 4 | 권장 시작점 |
| ~300ms | 192–256 | 3 | 4–6 | 고강도 인증에 적합 |
메모리 제약 환경 (서버리스/저사양)
목표 지연 m (MiB) t p 비고
| ~100ms | 32–64 | 3–4 | 2–3 | 메모리 낮추고 반복↑ |
| ~200ms | 64–96 | 3–4 | 3 | 서버리스 고려 |
| ~300ms | 96–128 | 3–4 | 3–4 | 고비용 경로만 적용 |
고강도 보안 (관리자/금융)
목표 지연 m (MiB) t p 비고
| ≥300ms | 256–512 | 3–4 | 4–8 | 2FA/레이트리밋 병행 |
4. 구현 예시
Go
import (
"crypto/rand"
"encoding/base64"
"golang.org/x/crypto/argon2"
)
params := struct {
Memory uint32
Iterations uint32
Parallelism uint8
SaltLen uint32
KeyLen uint32
}{131072, 3, 4, 16, 32}
salt := make([]byte, params.SaltLen)
rand.Read(salt)
hash := argon2.IDKey([]byte(password), salt,
params.Iterations, params.Memory, params.Parallelism, params.KeyLen)
encoded := "$argon2id$v=19$m=131072,t=3,p=4$" +
base64.RawStdEncoding.EncodeToString(salt) + "$" +
base64.RawStdEncoding.EncodeToString(hash)
Node.js
import argon2 from "argon2";
const hash = await argon2.hash(password, {
type: argon2.argon2id,
timeCost: 3,
memoryCost: 128 * 1024,
parallelism: 4,
hashLength: 32,
saltLength: 16,
});
const ok = await argon2.verify(hash, input);
5. 운영 체크리스트
- 레이트 리미트 + 랜덤 지연 (타이밍 분석 방지)
- 유출 비밀번호 대조 (가입/변경 시 HIBP 등)
- 비밀번호 매니저 사용 권장
- 유니코드 정규화(NFC)
- Constant-Time 비교 사용
- 재해시 정책: bcrypt → Argon2id 마이그레이션 시 로그인 성공 후 즉시 재해시
6. 권위 자료
실무 권장 파라미터 (2025 기본값)
m=131072 (128 MiB), t=3, p=4, salt=16B, key=32B