깨끗한 3-state machine: fresh, warned, locked. 각 PIN 시도가 그 source IP 에 대한 state 진행시켜.
| State | Counter 범위 | 다음 시도에 일어나는 일 |
|---|---|---|
| Fresh | fail_count = 0 | PIN 검증; 실패 → 1로 증가 |
| Warned | 1 ≤ fail_count < max_retry | PIN 검증; 실패 → 증가; 성공 → 0 리셋 |
| Locked | fail_count ≥ max_retry | bcrypt 전 거부; IP blacklist 추가; admin release 해야 |
"성공 시 reset" trade
성공 로그인 시 counter reset 은 친절 — 정당한 오타 몇 번 후 맞춰도 lockout X. *안전*하기도 — 공격자가 PIN 모르니까 추측 성공으로 counter reset 못 함. 그러려면 추측 성공해야 하는데, 그 시점엔 이미 auth 성공해서 brute force 더 안 필요.