보안 모델¶
dealcode의 위협 모델은 좁고 의도적입니다: 외부인이 시퀀스를 읽거나 열거하지 못하게 한다. 암호화 제품이 아니고, 코드는 비밀이 아닙니다. 이 페이지는 키가 지키는 것과 지키지 않는 것을 솔직하게 정리한 것으로, 스펙(§10)과 설계 결정 기록을 압축한 내용입니다.
키가 지키는 것 — 지키지 않는 것¶
유일성은 키의 비밀성에 의존하지 않습니다. FF1이 순열이라는 구조적 성질에서 나옵니다. 키가 지키는 것은 예측 불가능성입니다: 키가 없으면 코드는 발급 순서나 물량에 대해 아무것도 드러내지 않습니다. 연속된 카운터가 흩어져 나오므로 나눠준 코드로 생산 속도를 추정할 수 없습니다(dealcode가 막으려고 존재하는 바로 그 독일 전차 문제).
코드는 인증 토큰이 아닙니다¶
코드 공간은 의도적으로 작습니다 — 그래서 코드가 짧은 것입니다(hex 길이
6이면 1,670만 개). 온라인에서 코드를 시도할 수 있는 공격자는
발급량 / 용량에 비례하는 확률로 성공합니다.
- 세션 토큰, API 키, 비밀번호 재설정/매직 로그인 링크 — 그 자체로
인증하는 값에는 dealcode를 쓰지 마세요. 128비트 이상 CSPRNG
토큰(
secrets.token_urlsafe(32)등)을 쓰세요. - 공개 코드 조회에는 기본 위생으로 레이트 리밋을 거세요: 코드 공간이 작으니 온라인 추측을 지루하게 만드는 것입니다.
- decode 성공은 코드가 키와 일관적이라는 것만 증명합니다 — 형식이 올바른 미발급 코드도 어떤 카운터로 복호화됩니다. 존재를 확정하는 것은 DB 조회이고 decode는 파싱입니다.
데이터 암호화에 쓰지 마세요¶
작은 도메인 위의 FF1에는 AES 보안 마진보다 훨씬 낮은 수준의 구별 공격이 알려져 있습니다. dealcode의 난독화 용도에는 수용 가능합니다 — 대안 순열들은 다른 면에서 더 나쁘고, 암호학적으로 더 강한 무언가를 써도 작은 코드 공간은 여전히 온라인에서 열거 가능하기 때문입니다(그건 암호가 아니라 레이트 리밋으로 막는 것입니다). 하지만 이 라이브러리로 기밀 데이터를 암호화하지는 마세요. 카운터를 난독화하는 것, 그게 전부입니다.
키가 유출되면¶
과거 모든 코드의 발급 순서가 드러납니다 — 모든 코드의 시퀀스상 위치가 공개됩니다. 유일성은 영향받지 않지만(애초에 비밀성에 의존하지 않았으니), dealcode를 도입한 이유였던 비연결성은 이미 발급된 모든 것에 대해 사라집니다.
키는 다른 운영 시크릿과 똑같이 다루세요:
- KMS/Vault, 환경별 키.
- 로테이션 = 새 네임스페이스 — 키를 포함한 설정은 운영 중인 네임스페이스에서 동결입니다(이유). 기존 코드는 기존 설정에서만 복호화됩니다.
패스프레이즈 키¶
키 파생(SHA-256("dealcode/v1/kdf" ‖ 재료))은 도메인 분리이지 패스워드
스트레칭이 아닙니다. 패스프레이즈 키의 강도는 정확히 그
패스프레이즈만큼입니다. 128비트 이상 랜덤 재료를 쓰세요:
openssl rand -hex 32.
작은 코드 공간¶
radix^min_length ≥ 100(FF1의 구조적 최소)까지의 설정도 지원되고 상호
운용됩니다 — 코너 케이스는 문서로 밀어내는 대신 지원한다는 원칙입니다.
하지만 무엇을 선택하는지는 알아야 합니다: NIST SP 800-38G Rev. 1은 최소
100만 크기의 도메인을 권고하고, 3자리 십진 코드 공간은 키가 있든 없든
누구나 손쉽게 열거합니다. 노출 수준에 맞는 첫 스테이지 크기를 고르세요.