복구 코드… 아니면 하나의 복구 코드?
Source: Dev.to
Overview
인증 논의는 보통 다음에 초점을 맞춥니다:
- Passkeys
- TOTP
- 하드웨어 토큰
- 패스워드리스
복구 메커니즘은 같은 수준의 분석이 거의 이루어지지 않지만, 복구가 실제 보안 경계를 정의합니다. 로그인은 강력하지만 복구가 약하면 시스템 전체가 약합니다.
Backup Code Lists (5–10 one‑time codes)
Properties
- 여러 개의 정적 토큰
- 일회용 사용
- 재생성 가능한 리스트
Typical Issues
- 사용자가 제대로 보관하지 않음
- 스크린샷이 찍힘
- 코드가 잊혀짐
- 엔트로피 분석이 이루어지지 않음
- “코드가 많다”는 이유만으로 보안이 있다고 가정함
Security Considerations
- 실제 중요한 것은 엔트로피입니다.
- 복구는 위임된 인증이 됩니다.
- 보안은 다음에 의존합니다:
- 이메일 계정 보호
- SIM 보안
- 외부 공격 표면
이는 위협 모델을 바꾸는 것이지 강화하는 것이 아닙니다.
Seed Phrases (12–24 words)
Characteristics
- 개인 키 복구
- 높은 엔트로피
- 오프라인 저장 기대
Usability
- 암호학적으로 엄격하지만 사용성 비용이 높음.
Assumptions
- 공격자가 복구 엔드포인트에 접근 가능
- 데이터 유출 없음
- 내부 침해 없음
- 공격은 순수히 온라인에서만 발생
Security Depends On
- 엔트로피
- 생성 품질
- 속도 제한
발행된 코드 수에 의존하지 않습니다.
Tested Configuration
- Length: 15 characters
- Alphabet size: 31 symbols (ambiguous characters such as
0/Oand1/I/Lexcluded) - Generation: CSPRNG (
crypto.randomBytes) with rejection sampling (no modulo bias) - TTL: No fixed TTL
- Rate limiting: Strict; a few attempts within several minutes
- Rotation: Automatic after successful use
Entropy Calculation
- Alphabet size: 31
- Total search space: (31^{15})
- Entropy: ≈ 78 bits
Aggressive Attack Scenario
- Attempts: ~1.5 million per year
- Probability of success: Negligible (effectively infeasible for an online attack)
10개의 코드를 발행한다고 해서 단일 시도에 대한 엔트로피가 곱해지는 것이 아니라, 공격자는 여전히 하나씩 유효한 코드를 추측합니다.
Security Depends On
- 계정당 속도 제한
- 식별자당 스로틀링
- 코드당 엔트로피
- 올바른 무작위 생성
- 안전한 저장 모델
사용자에게 제공되는 출력 가능한 토큰 수에 의존하지 않습니다.
Randomness
// Use a cryptographically secure PRNG
const crypto = require('crypto');
function generateCode(length, alphabet) {
const bytes = crypto.randomBytes(length * 2); // oversample
let result = '';
let i = 0;
while (result.length < length && i < bytes.length) {
const idx = bytes[i] % alphabet.length;
// Rejection sampling to avoid modulo bias
if (bytes[i] < 256 - (256 % alphabet.length)) {
result += alphabet[idx];
}
i++;
}
return result;
}
Math.random()사용을 피하세요.- 바이트를 알파벳에 매핑할 때 모듈로 바이어스를 없애기 위해 거부 샘플링을 사용하세요.
Rate Limiting
Critical Points
- 복구 식별자당 제한 (IP만이 아니라).
- 계정당 및 IP당 제한을 결합.
- 필요하면 지수 백오프를 추가.
Rotation
복구가 성공한 후:
- 이전 코드를 무효화한다.
- 새 코드를 생성한다.
- 장기 정적 토큰을 피한다.
Conclusion
복구는 UX에 대한 사후 생각이 아니라 인증 원시 요소입니다. 복구 엔트로피와 시도 제어가 제대로 설계된다면, 단일 복구 코드만으로도 온라인 위협 모델 하에서 충분히 안전할 수 있습니다.
진정한 질문은 **“코드가 몇 개인가?”**가 아니라 “엔트로피는 얼마이며 공격 표면을 어떻게 제어하고 있는가?” 입니다.