logo

English

이곳의 프로그래밍관련 정보와 소스는 마음대로 활용하셔도 좋습니다. 다만 쓰시기 전에 통보 정도는 해주시는 것이 예의 일것 같습니다. 질문이나 오류 수정은 siseong@gmail.com 으로 주세요. 감사합니다.

Linux /dev/random vs /dev/urandom 삽질 후기

by 엉뚱도마뱀 posted Nov 22, 2017
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print

난수를 발생시키기 위해서 여러 가지 방법을 사용하는데 몇몇 가지 대표적인 예를 들어 보죠.

1. ANSI C 라이브러리의 rand() 함수를 이용한다.
2. 외부 라이브러리가 (apr 이나, openssl 같은...) 가 제공하는 random 함수들을 이용한다
3. 디바이스 파일을 이용한다 (/dev/random, /dev/urandom)
4. PRNGd 같은 데몬을 이용한다.

여기서 삽질을 겪었던 방법이 3번입니다.

암호화를 위한 아파치 모듈을 하나 만들었는데, 모듈에서 종종 난수를 발생하기 위해서 apr (apache portable runtime library) 에 있는 apr_generate_random_bytes() 라는 함수를 콜하도록 했었고요.

스테이지 테스트까지는 별 문제가 없었는데, 라이브 서버에 올렸더니 일정 시간이 지나면.. apache 가 hang 걸린것 처럼 멈춰 버리는 현상이 발생을 하더군요.

strace 로 system call 을 모니터링 해봤는데, 


open("/dev/random", O_RDONLY) = 28
read(28, 0x37ef8824, 4) = ...


여기서 wating 을 하고 있는 것이 아닌가... 몇초도 아니고 몇십초를 대기하고 있었다. 대략 1~2분 정도를..
아파치 소스를 까봤더니 apr_generate_random_byte 내부에서 /dev/random 디바이스를 오픈해서 그냥 읽도록 되어 있었네 그랴.
근데 왜 /dev/random 을 읽다가 wating을 할까....???

man 에서 그 해답을 찾았습니다.

리눅스에서는 /dev/random 과 /dev/urandom 두개를 PRNG 디바이스로 제공을 하는데
방식은 IO 디바이스 드라이버에서 발생하는 입력 신호의 노이즈를 게더링 하여 비트수를 연산하여 난수를 발생시킨다고 하는군요.

/dev/random, /dev/urandom 두개의 차이점은 전자는 엔트로피(얼마나 고른 난수를 발생 시킬 수 있을지를 결정할 수 있는 값이라는군요)가 충분해 져야만 난수를 발생 시키기 때문에 보안에 강하지만 느리고요(심지어지는 엔트로피가 채워잴때까지 blocking 합니다.), 후자는 이 값이 충분하지 않아도 발생을 시키긴 하는데 보안에 취약하지만 빠릅니다.(엔트로피가 채워질때까지 blocking 하지 않습니다. 현재있는 앤트로피만 가지고 생성을 한답니다.)

여기서 보안에 강하다 취약하다는 말은.. 발생된 random 값으로 암호화 키를 생성하는데 사용할 경우, 이 키가 얼마나 깨기 어렵느냐 쉬우냐를 얘기합니다.

서버와 같은 머신에서는 PC 와는 다르게, 키보드나, 마우스와 같은 IO 디바이스가 별로 없기 때문에 일정한 수준의 앤트로피 풀을 만들어 내는데 많은 시간이 걸린다고 합니다.

그리고 /dev/random 은 머신 자체의 영향도 많이 받습니다. 라이브 서버가 5년 전에 들어온 리눅스 머신이었고 스테이지 서버가 들어온지 1년도 안된 새삥 머신이었죠.. /dev/random 에서 wating 하는 걸 두대에서 측정해 봤더니 스테이지 서버가 라이브 서버보다 상당히 빠르더군요..

그래서 결국은 apr 에서 제공하는 random 대신에 /dev/urandom 을 직접 오픈해서 읽는 걸로 바꾸었더니 행 걸리는 현상이 없이 잘 동작 하드랍니다.

참고로 FreeBSD 의 경우에는 /dev/random 은 Linux 의 /dev/urandom 과 같은 방식입니다.
FreeBSD 의 /dev 를 자세히보면 random 이 urandom 으로 symbolic link 가 걸려 있는걸 알 수 가 있습니다.


List of Articles
No. Subject Author Date Views
104 ALM의 등장 배경, 오해와 진실 digipine 2017.10.28 376
103 ATmega8 MCU 간의 TWI 기능을 이용한 I2C 통신 digipine 2017.11.02 5986
102 AWS EC2 Ubuntu 용 Docker 설치 스크립트 digipine 2021.09.01 345
101 Bitbucket에서 SSH 키 등록하고 사용하는 방법 (맥/리눅스) file lizard2019 2023.06.22 858
100 C/C++ struct 패딩(padding) 원리 이해 lizard2019 2019.03.04 2149
99 Certbot으로 무료 인증서 발급 받기 digipine 2020.09.03 522
98 CMM / CMMI 란 무엇인가? digipine 2017.10.28 2467
97 Compile FFmpeg on Ubuntu, Debian, or Mint digipine 2017.11.02 327
96 Docker Compute Engine Ubuntu에서 Docker 설치 방법 lizard2019 2021.04.15 463
95 Docker 모든 컨테이너를 Stop 또는 Remove 하는 방법 digipine 2021.09.01 202
94 Docker에서 Phabricator 최신버전 설치 및 버전 확인 방법 file lizard2019 2021.04.15 1400
93 FFServer RTSP Audio Server Config digipine 2023.05.12 224
92 FFT (Fast Fourier Transform) 고속 푸리에 변환 예제 소스 digipine 2017.10.29 12544
91 gcc thread and mutex 사용법 lizard2019 2019.02.27 1198
90 Git Commit 취소 관련 명령어 정리 1 digipine 2017.11.02 1327
89 Git Commnd 사용법 정리 digipine 2017.11.02 263
88 Git Http Backend Upload Size 설정 - Http 500 Error 해결 digipine 2017.11.02 2074
87 Git 서버 구축 - 우분투[Ubuntu] digipine 2017.11.02 307
86 git 환경 설정 및 명령어 정리 digipine 2017.11.03 425
85 Golang Channel 사용법 정리 digipine 2021.10.22 414
Board Pagination Prev 1 2 3 4 5 6 Next
/ 6