암호학적 난수와 엔트로피: 키·토큰·Nonce 생성의 기본 조건
1장 개념과 보호 목표#
암호학적 난수는 통계적으로 불규칙할 뿐 아니라 공격자가 과거 출력으로 다음 값을 예측하기 어려워야 합니다. 키, 세션 토큰, 비밀번호 재설정 링크에는 CSPRNG 같은 보안용 난수 생성기가 필요합니다.
2장 원리와 구분#
엔트로피는 공격자가 모르는 정보의 양과 관련됩니다. 긴 출력이라도 시드를 시간값처럼 추측 가능한 값 하나로 만들면 키 후보가 제한됩니다. 일반 시뮬레이션용 PRNG는 보안용으로 설계되지 않을 수 있습니다. Nonce는 알고리즘에 따라 유일성이 핵심이고 CBC의 IV처럼 예측 불가능성까지 필요한 경우도 있습니다.
3장 비교와 판단 기준#
| 생성 대상 | 필요한 성질 | 대표 점검 |
|---|---|---|
| 암호키 | 충분한 엔트로피·예측 불가능성 | CSPRNG·표준 파라미터 |
| 재설정 토큰 | 예측 불가능성·충분한 공간 | 만료·일회성·안전한 전달 |
| GCM Nonce | 동일 키에서 유일성 | 재시작·복제·충돌 확률 |
| CBC IV | 예측 불가능성 | 새 암호화마다 안전하게 생성 |
4장 무작위처럼 보이는 값과 예측 불가능한 값#
일반 난수 생성기는 시뮬레이션이나 게임에서 충분할 수 있지만 공격자가 상태나 시드를 추측하는 상황까지 요구하지 않을 수 있습니다. 보안 토큰에는 이전 출력을 보더라도 다음 값을 예측하기 어렵도록 설계된 CSPRNG가 필요합니다. API 이름에 random이 있다는 사실만으로 이 조건을 판단하지 않습니다.
시각·프로세스 번호·사용자 ID는 길게 이어 붙여도 공격자가 후보를 크게 줄일 수 있습니다. 출력 문자열의 길이와 실제 엔트로피는 다릅니다. 키·재설정 토큰·Salt·Nonce는 서로 다른 요구를 갖지만 생성기의 적합성부터 확인해야 합니다.
5장 엔트로피를 후보 공간으로 읽기#
균등하게 선택한 b비트 비밀의 후보는 2^b개입니다. 한 번의 무작위 추측 성공 확률은 1/2^b입니다. 여러 시도의 누적 성공 가능성과 실제 생성기의 편향을 함께 고려해야 합니다. 겉모양만 보고 길이를 비트 강도로 환산하면 안 됩니다.
안전한 무작위 바이트 → 표현 형식으로 인코딩 → 토큰
시간과 사용자 번호 조합 → 보기 긴 문자열 → 예측 가능한 토큰일 수 있음6장 인코딩은 비밀의 양을 늘리지 않는다#
Base64·16진수는 바이트의 표현을 바꿉니다. 같은 원본을 길게 표시해도 엔트로피는 늘지 않습니다. 예를 들어 같은 바이트를 16진수로 표시했을 때 문자열 자릿수와 원래 바이트 수를 혼동하지 않아야 합니다. URL용 인코딩은 전달 편의를 위한 선택입니다.
랜덤 바이트를 일부만 잘라 쓰거나 문자 목록에 매핑할 때도 편향·길이 조건을 확인합니다. 검증된 토큰 생성 기능을 사용하면 직접 만든 변환의 실수를 줄일 수 있습니다.
7장 CSPRNG의 초기 상태와 출력#
안전한 난수 생성은 엔트로피 수집과 상태 관리, 정해진 출력 생성에 관련됩니다. 애플리케이션이 직접 시간 시드를 넣거나 검증된 생성기를 자체 코드로 대체하면 운영체제의 보호를 우회할 수 있습니다. 일반적으로 OS나 암호 라이브러리의 보안 API를 사용합니다.
flowchart LR
E["엔트로피와 시스템의 안전한 초기화"] --> S["CSPRNG 상태"]
S --> O["보안 난수 출력"]
O --> K["키·토큰·필요한 값 생성"]
K --> V["목적별 길이와 수명 조건 적용"]8장 테스트용 고정 시드가 운영으로 넘어가는 경로#
재현 가능한 테스트에는 고정 시드가 유용할 수 있습니다. 그러나 같은 코드·환경변수·설정 파일이 운영에 반영되면 키와 토큰이 예측 가능한 순서로 생성될 수 있습니다. 테스트용 생성기와 운영용 API의 연결을 명확히 분리하고 배포 설정을 확인합니다.
생성 실패를 고정 값이나 빈 값으로 바꾸는 예외 처리도 위험합니다. 난수 생성이 실패하면 해당 보안 작업이 안전하게 중단되어야 하며 조사 가능한 경보를 남깁니다.
9장 프로세스 복제와 재시작을 시험한다#
사용자 공간 생성기의 상태를 그대로 복제하면 여러 프로세스가 같은 출력 순서를 만들 수 있습니다. 실제 사용하는 OS·라이브러리가 복제와 재초기화를 어떻게 처리하는지 확인합니다. 컨테이너 이미지에 키나 고정 상태를 넣어 모든 인스턴스가 공유하는 경로도 조사해야 합니다.
단순히 많은 출력을 생성해 중복이 없었다는 결과는 예측 불가능성의 증명이 아닙니다. 생성기의 구조·시드·상태 보호와 목적별 사용 조건이 중요하며 통계 시험은 그중 일부 관측일 뿐입니다.
10장 재설정 토큰의 생성 이후 수명주기#
토큰은 특정 계정·목적·유효기간에 연결하고 한 번만 소비되도록 합니다. 발급을 반복했을 때 이전 토큰이 계속 유효한지, 탈퇴·비밀번호 변경 뒤 토큰이 회수되는지 정책을 정합니다. 토큰의 강도와 만료는 서로 다른 통제입니다.
flowchart TB
G["안전한 토큰 생성"] --> S["계정·목적·만료와 저장"]
S --> D["허용 채널로 전달"]
D --> V["토큰과 상태 검증"]
V --> C["원자적 단일 소비"]
C --> R["필요한 세션·다른 토큰 회수"]11장 고엔트로피 토큰의 저장과 비밀번호 저장#
무작위 토큰은 충분한 후보 공간을 확보하면 서버가 해시값을 저장해 원문 토큰의 직접 노출을 줄이는 구성을 사용할 수 있습니다. 사람의 비밀번호는 후보가 적을 수 있어 전용 KDF로 비용을 높이는 요구가 있습니다. 둘 다 해시로 저장할 수 있다고 같은 비용 설계를 적용하지 않습니다.
토큰을 URL로 전달할 때는 로그·분석·리퍼러·화면 캡처와 메일 전달 경로를 고려합니다. 발급된 토큰의 원문을 불필요하게 다시 출력하지 않고 검증 결과와 사건 식별자를 기록합니다.
12장 두 요청이 동시에 같은 토큰을 사용하면#
단순히 사용 여부를 조회한 뒤 나중에 표시하면 두 요청이 모두 미사용 상태를 읽을 수 있습니다. 소비와 상태 변경을 원자적으로 처리하거나 동등한 보장 구조를 사용합니다. 실패·재시도·중복 요청의 결과도 일관되게 설계해야 합니다.
| 시험 | 기대 결과 | 확인할 경계 |
|---|---|---|
| 만료된 토큰 | 거부 | 시각 기준과 만료 비교 |
| 다른 계정에 적용 | 거부 | 계정·목적 결합 |
| 두 번 사용 | 한 번만 성공 | 원자적 소비 |
| 생성기 실패 | 발급 중단 | 고정 대체값 사용 금지 |
| 로그 조사 | 원문 비밀 없음 | URL·추적 수집 범위 |
13장 적용 사례와 운영 방법#
운영체제와 언어가 제공하는 보안 난수 API를 사용하고 자체 시드를 주입하는 코드는 피합니다. 컨테이너 복제, 가상머신 스냅샷 복원, 기기 초기 부팅에서 상태가 반복되는지 확인합니다. 토큰에 유효기간과 일회성 사용 정책을 더하면 난수 품질 외의 위험도 줄일 수 있습니다.
14장 긴 문자열과 높은 엔트로피는 다르다#
32자리 토큰이라도 시간과 사용자 번호를 조합해 예측할 수 있으면 안전한 비밀이 아닙니다. 엔트로피는 문자열의 겉모양보다 공격자가 후보를 얼마나 줄일 수 있는지와 관련됩니다. 균등한 b비트 토큰을 한 번 추측해 맞힐 확률은 2^-b이지만 생성 방식이 편향되거나 내부 상태가 드러나면 이 계산이 성립하지 않습니다.
운영에서는 OS나 검증된 암호 라이브러리의 CSPRNG API를 사용합니다. 시간으로 직접 시드한 일반 의사난수 생성기, 개발용 고정 시드, 프로세스 복제 후 동일 상태를 사용하는 코드가 없는지 조사합니다. 난수 통계 테스트를 통과했다는 사실만으로 예측 불가능성을 증명할 수는 없습니다.
15장 비밀번호 재설정 토큰을 끝까지 보호하기#
토큰은 충분한 무작위성을 갖춰 생성하고 단일 사용·짧은 유효기간·사용자 및 목적 결합을 적용합니다. 서버 저장소가 유출될 때의 영향을 줄이려면 고엔트로피 토큰의 해시를 보관하는 구조를 검토할 수 있습니다. URL·로그·분석 도구·메일 전달 과정에서 토큰이 새어 나가는 경로도 확인합니다.
동시에 두 요청이 같은 토큰을 사용해도 한 번만 성공하도록 소비 처리를 원자적으로 수행합니다. 토큰 추측 실패, 만료, 재사용 시험을 각각 준비해야 생성기의 품질을 실제 인증 절차의 안전성으로 연결할 수 있습니다.
16장 적용 전 확인할 사항#
- 보안 난수 API와 일반 난수 API를 구분한다
- 복제·재시작 이후 값이 반복되지 않는지 확인한다
- 키 길이뿐 아니라 시드와 토큰 만료 정책을 점검한다
17장 자주 묻는 질문#
랜덤 문자열이 길면 무조건 안전한가요?#
생성기의 예측 가능성과 출력 공간, 유출 경로에 따라 달라집니다. 안전한 난수와 충분한 길이, 서버 측 만료·사용 제한을 함께 적용해야 합니다.
UUID는 모두 보안 토큰으로 쓸 수 있나요?#
UUID의 버전과 생성 방식마다 특성이 다릅니다. 식별자의 유일성 요구와 비밀 토큰의 예측 불가능성 요구를 구분하고 해당 보안 목적에 맞는 생성 API를 사용해야 합니다.
Base64로 인코딩하면 난수 강도가 높아지나요?#
인코딩은 표현 방식만 바꿉니다. 원래 바이트의 엔트로피를 늘리지 않으며 인코딩 전 안전한 난수 생성이 필요합니다.