수정 이력(5건, 최종 수정 2026년 09월 03일)
이 글에 적용한 변경 사항의 기록입니다. 보관해 둔 수정 전 버전은 DOI가 부여된 고정 URL에서 읽을 수 있습니다.
- permalink·저자 표기·지식 맵 래퍼·깨진 내부 링크 등 CI가 지적한 표시용 수정을 반영했습니다. 본문의 기술적인 주장은 바꾸지 않았습니다.
- 글 맨 앞에 「이 글의 지식 맵」 절을 추가했습니다. 본문에서 다루는 개념과 그 관계를 요약·그림·상세 페이지 링크로 모은 것입니다. 본문의 주장은 바꾸지 않았습니다.
- 외부 리뷰(1283건)에 대응해 본문을 갱신했습니다. 개별 변경 내용은 아래 이력을 참조하세요.
- 일상어와 규격 용어, 영어 전개의 대응표를 추가했습니다(CSPRNG와 TRNG가 NIST 용어가 아니라는 점도 주석했습니다). C#과 Python으로 최소 사용 예를 넣고, `random`을 쓰면 안 되는 대비도 두었습니다. 시각을 seed로 한 토큰이 추측되는 실제 피해 시나리오도 추가했습니다.
- 글 안에서 「擬似乱数」와 「疑似乱数」 표기가 섞여 있던 것을 「의사난수」로 통일했습니다(출처 문서명은 원문 그대로입니다).
- 최초 공개
이 글을 인용하기(DOI: 10.5281/zenodo.21635264)
이 글은 Zenodo에 보관되어 있습니다. 항상 최신 버전으로 연결되는 DOI와 지금 보고 있는 버전에 고정된 DOI를 아래에 함께 제시합니다.
Go Komura (2026). 「의사난수와 진짜 난수의 차이 - 어떻게 구별하는지 정리」. 합동회사 코무라소프트. https://doi.org/10.5281/zenodo.21635264 https://comcomponent.com/ko/blog/pseudo-random-vs-true-random-how-to-distinguish/
- DOI(최신 버전)
- 10.5281/zenodo.21635264
- DOI(이 버전)
- 10.5281/zenodo.21635265
난수 이야기는 꽤 다른 것들이 전부 랜덤이라는 한 단어로 불리기 때문에, 금세 논의가 엇갈립니다. Math.random()처럼 계산으로 만드는 수열도, 열잡음이나 클록 지터 같은 물리 현상에서 얻는 수열도, 겉모습만 보면 어느 쪽이든 어느 정도 흩어져 보이기 때문입니다.
다만 실무에서 이 차이를 모호하게 두면, 다음 같은 판단을 그르치기 쉽습니다.
- 시뮬레이션에서 재현하고 싶은데 매번 결과가 흔들린다
- 비밀번호 재발급 토큰을 예측하기 쉬운 난수로 만들어 버린다
- 통계 검정에 통과했다는 이유만으로 「진짜 난수다」라고 생각한다
- 반대로
의사라는 말만 듣고 전부 위험하다고 오해한다
이 글에서는 의사난수란 무엇인가, 진짜 난수란 무엇인가, 어떻게 구별하는가를 실무에서 판단하기 쉬운 형태로 정리합니다. 특히 출력의 겉모습이 아니라 생성기의 구성을 보는 데 초점을 둡니다.
본문 내용은 2026년 4월 시점에 확인할 수 있는 NIST, IETF, OS, 언어 공식 자료를 전제로 정리했습니다.
목차
- 먼저 결론(한 마디로)
- 이 글에서 말하는 「의사난수」와 「진짜 난수」
- 먼저 한 장으로 정리
- 3.1. 관계도
- 3.2. 용어를 짧게 정리
- 의사난수란 무엇인가
- 4.1. 한 마디로 말하면
- 4.2. 보통의 PRNG와 CSPRNG는 나눠 생각한다
- 진짜 난수란 무엇인가
- 5.1. 한 마디로 말하면
- 5.2. 물리 난수도 그대로 쓴다고는 할 수 없다
- 무엇이 다른가
- 6.1. 생성원
- 6.2. 재현성
- 6.3. 예측 가능성
- 6.4. 속도와 운용
- 어떻게 구별하는가
- 7.1. 출력만으로는 원칙적으로 완전히 구별할 수 없다
- 7.2. 먼저 봐야 할 것은 생성기의 설계
- 7.3. 다음으로, 통계 검정으로 명백한 결함을 찾는다
- 7.4. 보안 용도에서는 공격자 관점으로 본다
- 용도별로 무엇을 써야 하는가
- 8.1. 최소 사용 예
- 자주 있는 오해
- 실무에서 막힐 때의 판단표
- 정리
- 참고 자료
이 글의 지식 맵
이 글은 seed와 내부 상태에서 결정론적으로 수열을 만드는 의사 난수(PRNG)와, 열잡음 같은 물리 현상을 엔트로피 소스로 갖는 진짜 난수(NRBG)의 차이를 정리하고, 실무에서 사용하는 안전한 난수 API의 상당수가 물리 엔트로피 소스로 seed한 CSPRNG/DRBG의 하이브리드 구성임을 보입니다. 출력의 겉모습만으로는 둘을 구별할 수 없고, 통계 검정(NIST SP 800-22)도 증명이 아니라 결함 검출에 그치므로, 구별은 생성 알고리즘이나 seed의 출처와 같은 생성기 구성을 확인해 해야 한다고 합니다. 키·토큰·nonce·세션 ID와 같은 보안 용도에서는 시각 등 예측 가능한 값으로 seed하면 토큰이 추측되어 계정 탈취로 이어질 수 있으므로, BCryptGenRandom이나 .NET의 RandomNumberGenerator, Python의 secrets와 같은 OS·언어 표준의 secure RNG API를 써야 한다고 합니다.
flowchart LR
accTitle: 의사 난수와 진짜 난수의 차이의 지식 맵
accDescr: 의사 난수(PRNG)와 진짜 난수(NRBG)의 차이, 실무의 CSPRNG/DRBG가 엔트로피 소스와의 하이브리드 구성이라는 점, 통계 검정이 증명이 아니라 결함 검출에 그친다는 점, 예측 가능한 seed가 토큰 예측 공격으로 이어진다는 점을 보여주는 그림.
prng["의사난수(PRNG)"]
true_random_number_generator["진성 난수(NRBG/TRNG)"]
csprng_drbg["암호학적 의사난수(CSPRNG/DRBG)"]
entropy_source["엔트로피 소스"]
statistical_test_suite["통계 검정(NIST SP 800-22)"]
predictable_seed["예측 가능한 seed(시각·PID 등)"]
seed_prediction_attack["seed 추측 공격"]
account_takeover["계정 탈취"]
bcryptgenrandom["BCryptGenRandom"]
dotnet_randomnumbergenerator[".NET RandomNumberGenerator"]
linux_getrandom["getrandom()"]
python_secrets_module["Python secrets 모듈"]
java_securerandom["Java SecureRandom"]
security_token_generation["키·토큰·nonce·세션 ID 생성"]
simulation_reproducibility["시뮬레이션·테스트 재현성"]
session_id["세션 ID"]
csprng_drbg -->|"전제로 한다"| entropy_source
true_random_number_generator -->|"전제로 한다"| entropy_source
csprng_drbg -.->|"에서 확인할 수 있다"| statistical_test_suite
true_random_number_generator -.->|"에서 확인할 수 있다"| statistical_test_suite
predictable_seed -->|"원인이 될 수 있다"| seed_prediction_attack
seed_prediction_attack -.->|"원인이 될 수 있다"| account_takeover
csprng_drbg -->|"방지한다"| seed_prediction_attack
bcryptgenrandom -.->|"구현을 담당한다"| csprng_drbg
dotnet_randomnumbergenerator -->|"이용한다"| csprng_drbg
linux_getrandom -->|"이용한다"| csprng_drbg
python_secrets_module -->|"이용한다"| csprng_drbg
java_securerandom -->|"이용한다"| csprng_drbg
csprng_drbg -->|"권장되는 대응"| security_token_generation
prng -->|"사용은 비권장"| security_token_generation
prng -->|"권장되는 대응"| simulation_reproducibility
prng -->|"사용은 비권장"| session_id
그림의 실선은 항상 성립하는 관계, 점선은 조건이 붙는 관계입니다(성립 조건은 상세 페이지의 관계별 설명에 적혀 있습니다). 관계 전체 목록(총 16건, 근거와 확신도 포함)과 주요 개념의 정의는 지식 맵 상세 페이지에 정리되어 있습니다(일본어). 데이터: JSON-LD / Turtle
1. 먼저 결론(한 마디로)
먼저, 꽤 거칠지만 실무에서 도움이 되는 말로 하면 이렇습니다.
- 의사난수는 내부 상태와 알고리즘에서 결정론적으로 만드는 수열입니다
- 진짜 난수는 열잡음이나 지터 같은 물리 현상을 entropy source로 가진 수열입니다
- 다만 실무에서 쓰는 안전한 난수 API의 상당수는 물리 난수를 그대로 돌려주는 것이 아니라, entropy source로 seed한
DRBG / CSPRNG를 돌려줍니다 - 그래서
겉모습이 무작위인가만으로는 구별할 수 없습니다. 봐야 할 것은 생성기의 구성, seed가 들어가는 방식, reseed, health test입니다 - 시뮬레이션이나 재현 시험에서는 의사난수의 재현성이 무기가 됩니다
- 키, 토큰, nonce 같은 보안 용도에서는 OS나 언어가 제공하는 안전한 난수 API를 쓰는 것이 기본입니다
결국 우선 이 셋으로 나눠 생각하면 빗나가기 어렵습니다.
- 그것은
보통의 PRNG이야기인가 - 그것은
암호학적 PRNG / CSPRNG / DRBG이야기인가 - 그것은
물리 entropy source를 가진 NRBG / TRNG이야기인가
2. 이 글에서 말하는 「의사난수」와 「진짜 난수」
이 이야기에서는 그냥 난수라고 하면 대상이 너무 넓습니다. 그래서 먼저 의미를 고정합니다.
- 의사난수(PRNG): seed와 내부 상태에서 결정론적 절차로 수열을 생성하는 것. 같은 조건이면 같은 열이 나옵니다
- 암호학적 의사난수(CSPRNG / DRBG): 의사난수의 한 종류이지만, 예측 불가능성을 중시한 것입니다. NIST SP 800-90A는 이 deterministic random bit generator를 정의합니다
- 진짜 난수: 일상어로는
진성난수나물리 난수를 가리키는 경우가 많습니다. NIST에서는NRBG(non-deterministic random bit generator)가 가까운 표현이며, entropy source를 항상 참조하고 정상 시에는 full entropy 출력을 가지는 것으로 설명됩니다
명칭이 분야마다 다르므로, 일상어와 규격 용어의 대응도 먼저 고정해 둡니다. 이후에는 맨 왼쪽 열의 명칭으로 통일합니다.
| 이 글에서의 명칭 | 자주 보는 다른 표현 | 대응하는 약어 | 영어 전개 |
|---|---|---|---|
| 의사난수 | 擬似乱数 | PRNG | pseudorandom number generator |
| 암호학적 의사난수 | 암호론적 의사난수, 암호용 난수 | CSPRNG, DRBG | cryptographically secure pseudorandom number generator, deterministic random bit generator |
| 진짜 난수 | 진성난수, 참 난수, 물리 난수, 하드웨어 난수 | NRBG, TRNG | non-deterministic random bit generator, true random number generator |
| entropy source | 노이즈원 | — | entropy source |
두 가지만 보완합니다.
- NIST SP 800-90A / 90B / 90C가 쓰는 말은
DRBG,NRBG,entropy source입니다.CSPRNG와TRNG는 규격 용어가 아니라 실무와 문헌에서 널리 쓰는 명칭입니다 - 일본어에서는
疑似와擬似가 둘 다 쓰입니다. 이 글에서는의사난수로 통일합니다. 참고 자료의 문서명만 원문 그대로입니다
여기서 중요한 것은 의사난수와 위험한 난수가 동의어가 아니라는 점입니다.
예를 들어 선형 합동법이나 단순한 xorshift 같은 고속 PRNG와, CTR_DRBG나 HMAC_DRBG 같은 CSPRNG는 둘 다 결정론적이지만, 보안상의 의미는 꽤 다릅니다.
3. 먼저 한 장으로 정리
3.1. 관계도
먼저 개념의 위치 관계를 한 장으로 보는 편이 빠릅니다.
flowchart LR
NOISE["물리 현상<br/>열잡음·지터 등"] --> ENT["entropy source"]
ENT --> SEED["seed / reseed"]
SEED --> DRBG["DRBG / CSPRNG<br/>난수를 빠르게 전개"]
DRBG --> API["OS / 라이브러리가 돌려주는 난수"]
STATE["내부 상태 + 수식"] --> PRNG["보통의 PRNG"]
PRNG --> OUT["겉모습은 무작위인 수열"]
여기서 중요한 것은, 앱이 받는 안전한 난수 API의 출력이 오른쪽 보통의 PRNG와도, 왼쪽 날것의 물리 노이즈와도 조금 다르다는 점입니다.
많은 구현은 왼쪽 entropy source로 seed / reseed한 뒤, 그 위에서 DRBG / CSPRNG로 빠르게 전개한 값을 돌려줍니다. NIST SP 800-90B와 800-90C는 바로 이 entropy source + deterministic generator 구성을 정리하는 문서입니다.
3.2. 용어를 짧게 정리
| 종류 | 무엇으로 만드는가 | 같은 조건에서 재현 | 무엇을 강하게 요구하는가 | 맞는 용도 |
|---|---|---|---|---|
| 보통의 PRNG | 수식과 내부 상태 | 가능 | 속도, 재현성 | 시뮬레이션, 게임, 테스트 |
| CSPRNG / DRBG | 암호 알고리즘 + seed | 가능 | 예측 불가능성 | 키, 토큰, nonce, 세션 ID |
| 진짜 난수 / NRBG | 물리 entropy source | 기본적으로 불가 | 물리적 불확정성, entropy | seed 공급, 인증 장치, 감사가 무거운 추첨 |
짧게 외운다면 이렇습니다.
- 보통의 PRNG는
재현할 수 있는 난수 - CSPRNG는
재현은 되지만, 밖에서는 예측하기 어렵게 만드는 난수 - 진짜 난수는
물리 현상에서 entropy를 꺼내는 난수
4. 의사난수란 무엇인가
4.1. 한 마디로 말하면
의사난수는 내부 상태를 갱신하면서 난수처럼 보이는 수열을 계산으로 만드는 것입니다.
같은 seed를 넣고, 같은 알고리즘으로, 같은 횟수만 꺼내면 같은 값 열이 나옵니다. 결점처럼 보이기 쉽지만, 시뮬레이션, 테스트, 디버그에서는 오히려 큰 이점입니다.
재현할 수 있기에 이 seed에서 버그가 난다, 어제 결과를 다시 비교하고 싶다는 운용이 됩니다.
4.2. 보통의 PRNG와 CSPRNG는 나눠 생각한다
여기가 가장 오해되기 쉬운 지점입니다. 의사난수 = 가짜 = 쓰면 안 된다가 아닙니다.
NIST SP 800-90A는 해시 함수나 블록 암호를 바탕으로 한 deterministic random bit generator를 정의합니다. 즉 암호 용도로 쓰이는 난수의 핵심도 상당 부분은 결정론적 생성기입니다.
차이는 단순한 난수다움이 아니라, 공격자가 보기에 예측하기 어려운지에 있습니다.
- 보통의 PRNG
- 빠르다
- 재현하기 쉽다
- 내부 상태나 seed가 새면 예측되기 쉽다
- CSPRNG / DRBG
- 이것도 결정론적이다
- 다만 내부 상태를 모른다는 전제에서 출력을 예측하기 어렵게 설계된다
- 보안 용도에서는 이쪽을 쓴다
그래서 의사난수인가만으로 안전성을 판단하면 거의 빗나갑니다. 봐야 할 것은 어떤 의사난수인가입니다.
5. 진짜 난수란 무엇인가
5.1. 한 마디로 말하면
진짜 난수는 열잡음, 발진기 지터, 애벌랜치 노이즈, 양자 현상 같은 물리적 불확정성에서 entropy를 꺼내는 것입니다.
일상어로는 진성난수나 물리 난수라고 부릅니다. NIST 용어로는 NRBG가 가깝고, 항상 entropy source에 접근하며, 정상 동작하는 한 full entropy 출력을 가지는 생성기라는 위치입니다.
5.2. 물리 난수도 그대로 쓴다고는 할 수 없다
여기도 중요합니다. 진짜 난수라고 해서 생 측정값을 그대로 앱에 넘긴다고는 할 수 없습니다.
물리 난수원에는 실무상의 어려움이 몇 가지 있습니다.
- 편향이 있다
- 온도, 전원, 고장, 열화의 영향을 받는다
- 생 출력 속도가 그리 높지 않은 경우가 있다
- health check 없이는 고장 나도 알아채기 어렵다
이 때문에 NIST SP 800-90B에서는 entropy source의 설계 원칙, min-entropy의 생각법, validation test, health testing이 중시됩니다. 구현 전체로는 NIST SP 800-90C처럼 entropy source + DRBG 구성으로 쓰는 경우가 많습니다.
결국 진짜 난수는 raw의 신비한 무엇이 아니라, 물리 난수원, 평가, 감시, 후처리까지 포함해 다루는 것입니다.
6. 무엇이 다른가
난수의 차이는 단순히 무작위로 보이는가만으로는 정리되지 않습니다. 적어도 이 네 축으로 보면 이해하기 쉽습니다.
6.1. 생성원
- 의사난수: 알고리즘과 내부 상태
- 진짜 난수: 물리 entropy source
여기가 가장 본질적인 차이입니다.
6.2. 재현성
- 의사난수: 같은 seed면 재현할 수 있다
- 진짜 난수: 같은 조건으로 다시 뽑아도 같은 값 열이 되기 어렵다
재현성은 테스트에서는 강점, 추첨에서는 약점이 될 수 있습니다.
6.3. 예측 가능성
- 보통의 PRNG: seed나 내부 상태를 읽으면 앞이 꽤 보인다
- CSPRNG: 내부 상태가 지켜진다는 전제에서 앞을 읽히기 어렵게 설계된다
- 진짜 난수: 물리 난수원이 건전하면 예측하기 어렵지만, 센서 불량이나 설계 미비는 별 문제다
보안에서는 이 축이 가장 중요합니다. 겉보기 흩어짐보다, 다음 값을 맞출 수 있는지가 핵심입니다.
6.4. 속도와 운용
- 의사난수: 고속, 안정, 구현하기 쉽다
- 진짜 난수: entropy 수집과 감시가 필요하고, 속도나 구현 비용에 제약이 있다
이 때문에 프로덕션 시스템에서는 진짜 난수만 또는 의사난수만의 양자택일이 아니라, 물리 entropy로 seed한 CSPRNG가 가장 현실적입니다.
7. 어떻게 구별하는가
7.1. 출력만으로는 원칙적으로 완전히 구별할 수 없다
가장 중요한 답은 이것입니다. 유한 개의 출력 열만 보고 이것은 진짜 난수다라고 단정할 수는 없습니다.
이유는 단순합니다. 지금 관측한 유한 길이 열과 완전히 같은 열을 돌려주는 결정론적 프로그램은 언제든 만들 수 있기 때문입니다. 극단적으로 말하면 그 열을 배열이나 ROM에 넣어 두고 순서대로 돌려주기만 하면 됩니다.
그래서 겉모습이 자연스러우니 진짜라고 말할 수 없습니다. NIST SP 800-22에서도 통계 검정은 어디까지나 첫걸음이며, 그것만으로 생성기의 타당성을 절대적으로 증명하는 것은 아니라고 되어 있습니다.
거꾸로 말하면, 좋은 CSPRNG는 출력만 봐도 꽤 구별하기 어렵게 만들어집니다. 여기서 구별할 수 없다는 오히려 설계 목표 쪽에 가깝습니다.
7.2. 먼저 봐야 할 것은 생성기의 설계
7.1의 답은 「출력만으로는 안 된다」였습니다. 그렇다면 무엇을 보는가. 보는 것은 출력이 아니라 생성기 그 자체입니다.
같은 균일 분포로 보이는 두 열이 있어도, 한쪽은 seed에서 계산으로 만들어졌고 다른 쪽은 물리 현상에서 가져온 것입니다. 이 차이는 열을 아무리 들여다봐도 겉으로 나오지 않습니다. 만드는 방법을 확인해야 비로소 알 수 있습니다. 즉 구별은 「관측」이 아니라 「확인」 작업입니다.
확인할 항목은 다음 다섯 가지입니다.
- 생성 알고리즘이 무엇인가
- 단순한 PRNG인가, DRBG / CSPRNG인가
- seed는 어디에서 오는가
- 고정 seed, 시각, PID 정도인가
- OS의 entropy source에서 오는가
- reseed하는가
- 기동 시 한 번만 seed하고 끝나는가
- 운용 중에도 다시 넣는가
- entropy source 검증이 있는가
- min-entropy 평가
- health test
- 고장 감지
- 어느 API를 쓰는가
- 자체 구현인가
- OS / 언어의 표준 API인가
다섯 가지를 전부 조사할 필요는 없습니다. 위에서부터 보고, 답이 나온 시점에서 멈춰도 됩니다. 실무에서는 맨 위의 생성 알고리즘이 무엇인가와 맨 아래의 어느 API를 쓰는가 둘로 결정되는 경우가 대부분입니다.
이 관점으로 보면 꽤 많은 경우를 구별할 수 있습니다.
seed를 고정하면 매번 같은 열이 나온다→ 의사난수물리 entropy source가 있고, validation / health test를 전제로 한다→ 진짜 난수원을 가진 설계OS의 secure RNG API를 호출한다→ 상당수는물리 entropy + CSPRNG의 하이브리드
7.3. 다음으로, 통계 검정으로 명백한 결함을 찾는다
통계 검정이 불필요한 것은 아닙니다. 오히려 중요합니다. 다만 역할은 증명이 아니라 결함 검출에 가깝습니다.
대표적으로는 이런 관점을 봅니다.
- 0과 1의 편향
- run의 편향
- 주기성
- 상관
- 근사 엔트로피
- 선형 복잡도
NIST SP 800-22나, 일본에서는 CRYPTREC의 난수 검정 미니멈 세트가 자주 참조됩니다. 이들은 그 열에 이상한 편향이나 구조가 없는가를 조사하는 데에는 유효합니다.
다만 여기서 합격해도 진짜 난수라고는 말할 수 없습니다. 잘 만든 CSPRNG도 보통 통과할 수 있고, 반대로 물리 난수원이어도 센서의 편향이나 고장으로 떨어질 수 있습니다.
검정의 위치는 대체로 이렇습니다.
- 통과한다: 일단 노골적인 결함은 보이기 어렵다
- 떨어진다: 무언가 이상할 가능성이 높다
- 그래서 진짜라고 증명할 수 있다: 거기까지는 말할 수 없다
7.4. 보안 용도에서는 공격자 관점으로 본다
비밀번호 재발급 토큰, 세션 ID, nonce, 키 생성 같은 용도에서는 질문이 진짜인가만으로는 부족합니다.
정말로 봐야 할 것은 공격자가 다음 값을 예측할 수 있는가입니다.
예를 들어,
- 현재 시각만으로 seed한다
- 프로세스 ID나 일련번호만 섞는다
- 자체 구현에서 seed 품질을 평가하지 않는다
random계열 API를 보안 용도에 가져다 쓴다
이 정도는 겉모습이 그럴듯하다만으로는 막을 수 없습니다.
구체적으로 무엇이 일어나는지를 하나 적어 둡니다.
비밀번호 재발급 토큰을 현재 시각을 seed로 한 PRNG로 만든다고 합시다. 공격자는 먼저 자기 계정으로 재발급을 요청해, 도착한 토큰을 하나 손에 넣습니다. 토큰과 요청한 시각을 알면, seed 후보는 그 전후 몇 초까지 줄어듭니다. 나머지는 후보마다 같은 알고리즘을 돌려, 노린 상대의 토큰으로 나오는 값을 차례로 시험하면 됩니다.
이때 공격자는 암호를 깨지 않았습니다. 생성기를 자기 쪽에서 재현했을 뿐입니다. 그 난수열이 통계 검정을 통과했는지도 관계없습니다. seed 후보를 셀 수 있는 시점에서, 그 값은 공격자에게 난수가 아니기 때문입니다.
같은 이야기는 세션 ID, 초대 코드, 일회용 비밀번호, 공개 폴더에 두는 임시 파일명에도 해당합니다. 추측되어도 큰 피해는 없다고 단언할 수 없는 것은 모두 secure RNG 쪽에서 만들어야 합니다.
IPA도 보안 관련 API나 기존 라이브러리를 파악하고, 안이한 자체 구현을 피하라고 권합니다. Python에서도 secrets 모듈을 random보다 우선해 쓰라고 명시되어 있습니다. Java에서는 SecureRandom이 그 위치입니다.
결국 보안에서는 의사난수인가 진짜인가보다 안전한 seed / entropy와 안전한 API를 쓰는가가 더 중요합니다.
8. 용도별로 무엇을 써야 하는가
| 용도 | 맞는 것 | 이유 |
|---|---|---|
| 시뮬레이션, Monte Carlo, 게임 로직 | 보통의 PRNG | 빠르고, seed로 재현할 수 있다 |
| 테스트 재현, 버그 재현 | 보통의 PRNG | 같은 입력을 재현할 수 있다 |
| 키, 토큰, nonce, 세션 ID | CSPRNG / OS의 secure RNG API | 예측 불가능성이 필요하다 |
| seed 공급, 감사나 설명 책임이 무거운 추첨 | 물리 난수원을 가진 설계, 또는 감사 가능한 구조 | 물리 entropy나 증적이 중요하다 |
일반 앱 개발에서 안전한 난수가 필요할 때 |
OS / 언어 표준의 secure RNG | 자체 구현보다 빗나가기 어렵다 |
구현 수준에서 무난한 고르기는 이렇습니다.
- Windows 네이티브:
BCryptGenRandom - .NET:
System.Security.Cryptography.RandomNumberGenerator - Linux:
getrandom() - Python:
secrets - Java:
SecureRandom
Windows의 BCryptGenRandom은 Microsoft Learn에서 NIST SP800-90의 CTR_DRBG를 준수하는 기본 공급자를 설명합니다. Linux의 getrandom()도 난수 바이트를 cryptographic purposes에 쓸 수 있다고 문서화되어 있습니다. .NET의 RandomNumberGenerator, Python의 secrets, Java의 SecureRandom도 각각 암호 용도를 의식한 API입니다.
8.1. 최소 사용 예
목록만으로는 손이 움직이지 않으니, 대표적인 두 가지만 실제 형태를 올립니다. 둘 다 seed를 스스로 준비하지 않는다는 점이 공통입니다. seed 조달은 API 쪽 일입니다.
C#(.NET 8)에서는 System.Security.Cryptography.RandomNumberGenerator의 정적 메서드를 씁니다.
using System;
using System.Security.Cryptography;
// 0 이상 100 미만의 정수를 편향 없이 뽑는다
int n = RandomNumberGenerator.GetInt32(0, 100);
// 토큰용으로 32바이트를 뽑아 URL에 실을 수 있는 문자열로 만든다
byte[] bytes = RandomNumberGenerator.GetBytes(32);
string token = Convert.ToBase64String(bytes)
.Replace('+', '-')
.Replace('/', '_')
.TrimEnd('=');
GetInt32를 쓰는 이유는, 단순히 「바이트 열을 범위로 나눈 나머지」로 하면 끝쪽 값만 나오기 쉬워지기 때문입니다. 범위 지정이 필요할 때는 직접 나머지를 취하지 말고 이쪽을 씁니다.
Python(3.6 이후)에서는 secrets 모듈입니다.
import secrets
# URL에 실을 수 있는 안전한 토큰
token = secrets.token_urlsafe(32)
# 0 이상 100 미만의 정수
n = secrets.randbelow(100)
대비로, 다음은 같은 용도에 쓰면 안 되는 작성법입니다.
import random
# NG: random은 재현성을 위한 PRNG이며, 보안 용도가 아니다
token = "".join(random.choices("abcdefghijklmnopqrstuvwxyz0123456789", k=32))
random과 secrets는 둘 다 겉보기에는 흩어진 문자열을 돌려줍니다. 차이는 출력이 아니라 난수가 어디에서 왔는가입니다. random은 Mersenne Twister를 쓰는 재현성 중시 PRNG이며, Python 공식 문서에서도 비밀 관리에는 secrets를 쓰라고 안내합니다.
9. 자주 있는 오해
9.1. 통계 검정에 통과하면 진짜 난수이다
아닙니다. 그것으로 말할 수 있는 것은 노골적인 편향이 보이기 어렵다 정도입니다.
9.2. 진짜 난수이면 항상 안전하다
아닙니다. 물리 난수원의 고장, 편향, 구현 미비, health test 부재로 품질이 무너집니다.
9.3. 의사난수는 전부 위험하다
아닙니다. CSPRNG / DRBG는 오히려 실무의 안전한 난수 API의 핵심입니다.
9.4. 보안 용도에서는 raw 물리 난수만 직접 써야 한다
반드시 그렇지는 않습니다. 실제로는 물리 entropy source + CSPRNG 조합이 일반적입니다.
9.5. random이나 Math.random()도 충분히 흩어지니 token에 쓸 수 있다
용도가 다릅니다. 겉보기 흩어짐과 공격자로부터의 예측 불가능성은 별개입니다.
10. 실무에서 막힐 때의 판단표
막혔을 때 생각하는 순서는 이렇습니다.
- 같은 결과를 재현하고 싶은가
- 예 → 보통의 PRNG
- 아니요 → 다음으로
- 공격자에게 예측되면 곤란한가
- 예 → OS / 언어 표준의 secure RNG
- 아니요 → 품질 요건과 속도로 고른다
- 난수원 자체의 설명 책임이나 감사가 필요한가
- 예 → 물리 난수원이나 인증된 서비스를 검토한다
- 자체 구현하고 싶은가
- 마음은 이해하지만, 난수는 빗나가기 쉬우니 먼저 표준 API를 쓴다
이 순서로 보면 의사인가 진짜인가라는 양자택일만으로 고민하는 것보다 꽤 빨리 방침이 정해집니다.
11. 정리
의사난수와 진짜 난수의 차이를, 가장 거칠지만 실무에서 도움이 되는 형태로 말하면 이렇습니다.
- 의사난수는 계산으로 만든다
- 진짜 난수는 물리 현상에서 entropy를 꺼낸다
- 그러나 실무의 안전한 난수 API는 그 중간에 있는
entropy source + CSPRNG가 주역이다
즉 봐야 할 것은 겉모습이 아니라 구성입니다.
- 출력만으로 진짜인지를 단정할 수는 없다
- 통계 검정은 결함 검출에는 도움이 되지만 증명은 되지 않는다
- 보안에서는
예측할 수 있는가가 핵심이다 - 재현성이 필요하면 PRNG, 예측 불가능성이 필요하면 OS / 언어 표준의 secure RNG를 쓴다
이 순서로 잡으면 의사난수는 가짜인가라는 거친 대립에서 빠져나올 수 있습니다.
12. 참고 자료
-
NIST SP 800-90A Rev. 1: Recommendation for Random Number Generation Using Deterministic Random Bit Generators deterministic random bit generator의 기본 문서입니다.
-
NIST SP 800-90B: Recommendation for the Entropy Sources Used for Random Bit Generation entropy source, validation, health testing의 생각법을 정리합니다.
-
NIST SP 800-90C: Recommendation for Random Bit Generator (RBG) Constructions
entropy source + DRBG구성을 정리합니다. -
NIST SP 800-22 Rev. 1a: A Statistical Test Suite for Random and Pseudorandom Number Generators for Cryptographic Applications 통계 검정의 위치를 설명합니다. 검정은 첫걸음이며 증명이 아니라는 점이 중요합니다.
-
NIST Glossary: Non-deterministic Random Bit Generator (NRBG)
true random에 가까운 NIST 용어를 확인하는 데 쓸 수 있습니다. -
RFC 4086: Randomness Requirements for Security 보안 용도에서의 난수와 entropy source 주의점을 정리합니다.
-
Microsoft Learn: BCryptGenRandom function Windows의 secure RNG API와 기본 공급자의
CTR_DRBG를 설명합니다. -
Linux man page: getrandom(2) Linux에서
cryptographic purposes에 쓸 수 있는 난수 API입니다. -
Microsoft Learn: RandomNumberGenerator クラス .NET의 암호 강도가 높은 RNG API입니다.
-
Python documentation: secrets — Generate secure random numbers for managing secrets Python에서 보안 용도 난수를 다루는 기본입니다.
-
Oracle Java Documentation: SecureRandom Java의 secure RNG와 seed / entropy 생각이 정리되어 있습니다.
-
IPA: 第3章 3.破られにくい暗号技術と擬似乱数の使用 seed의 중요성, 검정, API 이용의 주의점이 일본어로 정리되어 있습니다.
관련 기사
같은 태그를 공유하는 최신 기사입니다. 더 가까운 주제로 지식을 넓힐 수 있습니다.
Windows 가상화의 심층(제2회) ── 커널에서도 보이지 않는 메모리: VBS·HVCI·Credential Guard의 구조
대응 하드웨어에 클린 설치하면 기본으로 켜지는 VBS는, 하이퍼바이저와 SLAT로 커널보다 강한 격리를 만듭니다. VTL, 보안 커널, HVCI, Credential Guard의 구조를 설명합니다.
Named Pipe 실무 ── Windows 프로세스 간 통신의 정석을 설계부터 보안까지
Windows의 프로세스 간 통신의 정석인 Named Pipe를 실무 관점에서 해설합니다. 바이트/메시지 모드 선택, 여러 클라이언트를 처리하는 서버 설계, ACL과 impersonation 보안, .NET NamedPipeStream까지 1차 ...
Windows 서비스 계정 선정 ── LocalSystem·가상 계정·gMSA를 구분해서 쓰기
Windows 서비스를 아직 LocalSystem으로 돌리고 있지는 않습니까. LocalService·NetworkService·가상 계정·도메인 사용자·gMSA의 권한과 네트워크상 신원을 판단표로 비교하고, 최소 권한으로 운영하는 고르는 법을 ...
Windows 보안 감사 정책과 이벤트 로그 조사 실무 ── 4625를 읽는 정보시스템 담당자가 되기
「로그온 실패 로그를 조사해 달라」는 요청에 답하기 위한 실무 가이드입니다. 기본 감사 정책과 고급 감사 정책의 관계, 최소한 활성화해야 할 하위 범주, 이벤트 ID 4624/4625/4688을 읽는 법, Security 로그의 용량 설계, Ge...
Windows LAPS 실무 가이드 ── 전 PC 공통 로컬 관리자 비밀번호를 그만두기
전 PC 공통 로컬 관리자 비밀번호는 한 대의 침해가 전대로 번지는 Pass-the-Hash 공격의 온상입니다. OS 표준 기능이 된 Windows LAPS의 자동 로테이션과 AD/Entra ID 저장 설정, 운영상의 함정을 설명합니다.
관련 토픽
이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.
Windows 기술 토픽
Windows 개발, 장애 조사, 기존 자산 활용에 관한 KomuraSoft LLC 기사를 모은 토픽 허브입니다.
이 주제와 연결되는 서비스
이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.
기술 상담 & 설계 리뷰
시뮬레이션용 재현성과 보안용 예측 불가능성을 어떻게 나눌지, 난수 API 선정이나 seed 설계부터 정리하고 싶을 때는 기술 상담·설계 리뷰로 다루기 쉬운 주제입니다.
자주 묻는 질문
이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.
- 의사난수와 진짜 난수(진성난수)의 차이는 무엇인가요?
- 의사난수(PRNG)는 seed와 내부 상태에서 알고리즘으로 결정론적으로 만드는 수열이며, 같은 조건이면 같은 열이 나옵니다. 진짜 난수는 열잡음이나 발진기 지터 같은 물리 현상을 entropy source로 가진 수열이며, 같은 조건으로 다시 뽑아도 같은 값 열이 되기 어렵습니다. 다만 실무에서 쓰는 안전한 난수 API의 상당수는 물리 난수를 그대로 돌려주는 것이 아니라, 물리 entropy source로 seed한 CSPRNG / DRBG를 돌려주는 하이브리드 구성입니다.
- 출력만 보면 의사난수인지 진짜 난수인지 구별할 수 있나요?
- 유한 개의 출력 열만 보고 진짜 난수라고 단정할 수는 없습니다. 관측한 열과 완전히 같은 열을 돌려주는 결정론적 프로그램은 언제든 만들 수 있기 때문입니다. 구별할 때는 출력의 겉모습보다, 생성 알고리즘이 무엇인지, seed는 어디에서 오는지, reseed하는지, entropy source 검증(min-entropy 평가나 health test)이 있는지, 어느 API를 쓰는지라는 생성기 구성을 확인하는 편이 본질적입니다.
- 통계 검정에 통과하면 진짜 난수라고 할 수 있나요?
- 말할 수 없습니다. 통계 검정의 역할은 증명이 아니라 결함 검출에 가깝습니다. NIST SP 800-22에서도 통계 검정은 어디까지나 첫걸음이며, 그것만으로 생성기의 타당성을 절대적으로 증명하는 것은 아니라고 되어 있습니다. 잘 만든 CSPRNG도 보통 검정을 통과하고, 반대로 물리 난수원이어도 센서의 편향이나 고장으로 떨어질 수 있습니다. 통과하면 노골적인 결함은 보이기 어렵고, 떨어지면 무언가 이상할 가능성이 높다는 위치입니다.
- 보안 용도에서는 어떤 난수 API를 쓰면 되나요?
- 키, 토큰, nonce, 세션 ID 같은 용도에서는 OS나 언어가 제공하는 안전한 난수 API를 쓰는 것이 기본입니다. 구체적으로는 Windows 네이티브라면 BCryptGenRandom, .NET이라면 System.Security.Cryptography.RandomNumberGenerator, Linux라면 getrandom(), Python이라면 secrets 모듈, Java라면 SecureRandom입니다. 현재 시각이나 프로세스 ID로 seed한 자체 구현이나, random 계열 API를 보안 용도에 가져다 쓰는 것은 피해야 합니다.