쓸툴.site
Tech & Story

Python random vs secrets: 로또 번호 생성기의 보안 취약점과 해결책

📅 2026-01-08 👨‍💻 에디터 K
Python random vs secrets: 로또 번호 생성기의 보안 취약점과 해결책

개발자라면 누구나 한 번쯤 import random을 사용해 본 경험이 있을 것입니다. 게임 아이템 드랍률, 비밀번호 초기화, 그리고 로또 번호 생성까지. '랜덤(Random)'은 프로그래밍에서 필수적인 요소입니다. 하지만 우리가 무심코 사용하는 이 랜덤 함수가 사실은 "예측 가능하다"는 사실을 알고 계신가요?

특히 금전적인 이득이나 공정성이 중요한 서비스(경품 추첨, 로또, 카드 게임)에서 기본 라이브러리를 그대로 사용했다가는 치명적인 보안 사고로 이어질 수 있습니다. 이번 포스팅에서는 쓸툴(K-Tools)의 로또 생성기를 개발하며 고민했던 '의사 난수(Pseudo-random)'의 한계와, 이를 극복하기 위해 도입한 '암호학적 난수(CSPRNG)'의 기술적 원리를 개발자 관점에서 깊이 있게 다뤄봅니다.

1. 메르센 트위스터(Mersenne Twister)의 함정

파이썬의 기본 random 모듈은 '메르센 트위스터'라는 알고리즘을 기반으로 합니다. 이 알고리즘은 속도가 매우 빠르고 통계적으로 매우 우수한 균등 분포를 보여주기 때문에 시뮬레이션 분야에서는 표준으로 쓰입니다. 하지만 '결정론적(Deterministic)'이라는 태생적인 한계가 있습니다.

난수 생성기는 초기값인 '시드(Seed)'에 의해 다음 숫자가 정해집니다. 보통 현재 시간(Timestamp)을 시드로 사용하는데, 만약 해커가 서버의 시간 정보를 밀리초 단위로 정확히 알아낼 수 있다면? 그 시점에 생성된 로또 번호나 아이템 결과를 역으로 계산해낼 수 있습니다. 실제로 과거에 특정 온라인 포커 게임에서 이 취약점을 이용해 상대방의 패를 예측하는 해킹 사례가 존재했습니다. 보안이 필요한 곳에 `random`을 쓰는 건 대문을 열어두는 것과 같습니다.

2. secrets 모듈: 운영체제의 엔트로피를 빌리다

이러한 보안 이슈를 해결하기 위해, 파이썬 3.6부터는 secrets 모듈이 추가되었습니다. 이 모듈은 알고리즘에 의존하는 것이 아니라, 운영체제(OS)가 제공하는 '암호학적으로 안전한 난수 생성기(CSPRNG)'를 래핑(Wrapping)한 것입니다.

구체적으로 리눅스 환경에서는 /dev/urandom 장치 파일을, 윈도우에서는 CryptGenRandom API를 사용합니다. 이들은 하드웨어의 미세한 소음, 디스크 I/O 반응 속도, 키보드 입력 타이밍 등 외부의 예측 불가능한 물리적 현상에서 '엔트로피(Entropy, 무질서도)'를 수집하여 난수를 만듭니다. 따라서 슈퍼컴퓨터가 와도 다음에 나올 숫자를 수학적으로 예측하는 것이 불가능합니다. 이것이 바로 쓸툴의 로또 번호가 '진짜 랜덤'인 이유입니다.

3. 실제 코드 비교: random vs secrets

개발자분들을 위해 간단한 코드 차이를 보여드립니다. 보안이 중요한 기능에는 반드시 아래와 같이 코드를 변경해야 합니다.

# [BAD] 예측 가능한 난수 (보안 취약)

import random

password = ''.join(random.choices(string.ascii_letters, k=10))


# [GOOD] 암호학적으로 안전한 난수

import secrets

password = ''.join(secrets.choice(string.ascii_letters) for i in range(10))

쓸툴은 단순히 기능을 구현하는 것을 넘어, 보이지 않는 곳의 데이터 신뢰성까지 고민합니다. 사용자는 버튼 한 번을 누르지만, 서버 내부에서는 가장 안전한 방식으로 숫자를 뽑아내고 있습니다. 로또 번호 생성기에서 그 차이를 확인해 보세요.

🛡️ 보안이 검증된 로또 생성기

단순한 재미로 뽑는 번호라도 그 과정은 공정해야 합니다. 쓸툴의 로또 생성기는 OS 레벨의 엔트로피를 사용하여 누구도 예측할 수 없는 완벽한 무작위성을 보장합니다. 당첨되면 그건 오로지 여러분의 운입니다!

이 글이 도움이 되셨나요?

친구들에게 공유하고 함께 이야기해보세요!

🤖