안녕하세요. 볼드나인 R&D센터에서 Backend개발자로 근무중인 황성현입니다.
이번 글에서는 난수(random number)에 대해서 가볍게 소개하고자 합니다.
여러분들은 개발 작업을 하면서 무작위 숫자, 즉 난수가 필요한 경험이 있으셨을까요?
Math.random()
JavaScript
복사
볼드나인에서는 Node.JS환경으로 서버를 운영하고 있기에, 간단한 난수가 필요할 경우에는 주로 Math.random()을 활용하고 있습니다.
보안 목적으로 사용할 수 있는 난수란 무엇이며, 컴퓨터는 난수를 어떤 방식으로 생성하는 걸까요?
두 가지 유형의 난수생성기를 보면서 컴퓨터가 어떻게 난수를 생성하는지 알아보겠습니다.
TRNG (True Random Number Generator)
•
TRNG(진정한 난수생성기)는 물리적 현상(전자 잡음, 방사선, 전기적 신호 등)을 활용하여 진정한 난수를 생성합니다.
예: CPU의 하드웨어 기반 난수 생성기 (intel RDRAND / 물리적 엔트로피 소스(열 소음, 전자 잡음 등을 활용))
•
장점:
◦
완벽에 가까운 무작위성
◦
암호학적 응용에 적합
•
단점:
◦
무작위성을 생성하는 데 물리적 시간이 걸림 (대량으로 빠르게 생성하기 어려움)
◦
물리적 현상을 측정할 수 있는 하드웨어에 의존해야 함
◦
동일한 난수를 다시 생성할 수 없어서 테스트나 시뮬레이션에 부적합
PRNG (Psuedo Random Number Generator)
•
의사 난수 생성기는 수학적 알고리즘을 기반으로 난수를 생성합니다.
초기값(Seed)에 따라 생성되는 난수의 흐름이 결정됩니다.
•
장점:
◦
대량의 난수를 빠르게 생성 가능
◦
동일한 Seed를 사용하면 같은 난수를 다시 생성 가능(재현 가능성)
•
단점:
◦
Seed가 유출되면 난수 흐름이 예측 가능
개발 목적으로는 대량의 난수가 필요한 경우가 많기에 주로 PRNG를 활용하게 되는데요, PRNG의 일종인 BBS를 단순화 시킨 사례를 통해 가볍게 설명해보겠습니다.
1.
mod는 모듈러 연산을 의미하며, JS에서 사용하는 % 연산자를 떠올리면 됩니다!
2.
p, q는 소수입니다. (암호학적으로 안전하기 위해서는 충분히 큰 소수를 활용) 즉 M은 두 큰 소수의 곱을 의미합니다.
3.
초기값이 3 그리고 p, q를 5, 7로 가정하면 M은 35이기에 두 번째 값은 3의 제곱인 9를 35로 나눈 나머지 값인 9가 됩니다. 반복해서 세 번째 값은 9의 제곱인 81을 35로 나눈 나머지 값인 46이 됩니다. (계속 반복하여 난수를 생성!)
이 난수생성기의 문제점이 하나 있는데, 위 난수생성과정을 살펴보면 알 수 있듯이 초기값과 p, q의 값을 알게되면 어떤 난수들이 생성될지 미리 알 수 있다는 점입니다.
처음에 소개했던 JS의 Math.random()같은 경우도 의사난수생성기의 일종인데, 고정된 시드 값을 사용하고 있어서 시드가 누출될 경우 위 사례 처럼 어떤 난수가 생성될지 예상할 수 있게 되는 문제가 있어 보안적인 목적으로 사용하지 말라고 권고 하는 것이라고 합니다.
보통 난수가 필요할 때 JS의 crypto등의 내장 라이브러리를 활용하거나 이미 잘 구현된 방법으로 난수를 생성하는 경우가 많아서 컴퓨터가 어떻게 난수를 만드는 지에 대해서는 생각해볼 기회가 별로 없었을 텐데요, 이 글을 통해서 난수와 보안에 대해서 고민해 볼 수 있는 계기가 되었기를 바랍니다.