10.3. 난수

많은 경우 보안적인 프로그램들은 적이 추측할 수 없는 임의의 숫자 (난수) 를 생성해야 하는데 예로는 많은 프로토콜, salt 등에 사용되는 세션키, 공개 또는 비밀키, 대칭키, nonces 와 IV 들이 있다. 이론상 난수로는 방사선 소멸 (가이거 카운터 클릭의 정확한 계시를 통해), 대기 소음 또는 전선에서의 열 소음에 기초한 값들과 같은 실제 무작위로 얻어진 데이타를 사용해야 한다. 어떤 컴퓨터는 실제 임의의 (random) 값을 생성하는 역할을 하는 하드웨어 컴포넌트를 갖고 있는데 가능하다면 이를 사용해야 한다.

그러나 대부분의 컴퓨터들은 실제 임의의 값들을 생성하는 하드웨어를 갖고 있지 않으며 따라서 대부분의 경우 적이 예측할 수 없을 만큼 충분히 임의적인 난수를 생성할 방법이 필요하다. 일반적으로 이는 다음 세가지를 필요로 함을 의미한다:

일반적으로 PRNG 는 상태를 사용해 어떤 값들을 생성한 후 이 값들중의 일부와 다른 추측할 수 없는 입력을 이용해 상태를 갱신한다. 이러한 시스템들을 공격하는 많은 방법들이 있는데 예를 들어 공격자가 상태에 대한 입력들 (또는 이들 중의 일부) 을 제어하거나 볼 수 있다면 공격자는 아마 난수를 결정할 수 있을 수도 있다.

PRNGs 를 사용하는데 있어 진짜 위험한 것은 대부분의 컴퓨터 언어 라이브러리들이 보안 목적에 부적절한 많은 PRNG 를 포함하고 있다는 것이다. 다시 한번 말하자: 보안을 목적으로 할 때 일반적인 난수 발생기를 사용하지 마라. 일반적으로 라이브러리 PRNG 는 모사, 게임 등에 사용하기 위한 것인데 이들은 키 생성과 같은 보안 함수들에 사용할 수 있을 정도로 충분히 임의적이지 않다. 대부분의 비암호화 라이브러리 PRNG 는 선형 합동 발생기 (linear congruential generator) 을 약간 변형시킨 것으로 ``다음" 임의의 값이 (aX+b)) mod) m 으로 계산된다 (X 는 이전 값이다). 훌륭한 선형 합동 발생기는 빠르며 유용한 통계적인 성질을 갖고 있어 의도한 사용 목적에 적절하다. 이러한 PRNG 와 관계된 문제는 차후의 값이 임의의 값으로 보임에도 불구하고 공격자에 의해 쉽게 추정될 수 있다는 것이다. 이차 (quadratic) 및 삼차 (cubic) 발생기와 같이 빠르게 난수를 생성하는 다른 알고리듬들도 해독되었다 [Schneier 1996]. 요약하면 보안적인 애플리케이션에서 난수를 생성하기 위해서는 암호학적으로 강력한 PRNG 를 사용해야 한다는 것이다 - 보통의 난수 라이브러리들은 충분하지 않다.

키에 대해 실제로 임의의 값들을 정확히 생성하지 못함으로써 Kerberos, X 윈도우 시스템과 NFS 시스템에서의 보안 구멍을 포함하여 많은 문제를 야기하였다 [Venema 1996].

가능하다면 암호학적으로 보안적인 임의의 값들을 생성하도록 특별히 설계된 일반적으로 운영체제에서 제공하는 시스템 서비스를 사용해야 한다. 예를 들어 리눅스 커널 (1.3.30 이후) 은 난수 발생기를 포함하고 있는데 이는 보안을 목적으로 한 많은 곳에 충분하다. 이 난수 발생기는 디바이스 드라이버와 다른 출처로부터의 환경 노이즈를 엔트로피 풀로 모으는데 /dev/random 으로 접근될 때 임의의 바이트들만이 엔트로피 풀에서 평가된 노이즈 비트수 내에서 반환된다 (엔트로피 풀이 비어있을 때 호출은 추가적인 환경 노이즈가 모여질 때까지 블록된다). /dev/urandom 으로 접근될 때는 엔트로피 풀이 다 고갈되었다 하더라도 요청된 만큼의 바이트들이 반환된다. 리눅스에서 키 생성과 같은 암호화 목적으로 임의의 값들을 사용하려면 /dev/random 을 사용해라. 하드웨어 난수 발생기를 사용할 수 있고 그 드라이버가 설치되어 있다면 이것이 대신 사용될 것임을 주목해라. 더욱 자세한 정보는 시스템 문서 random(4) 에서 얻을 수 있다.

다른 시스템에서는 정말로 임의적인 결과를 얻는 다른 방법으 찾아야 할 것이다. 다른 유닉스 계열 시스템에 대해서는 Entropy Gathering Daemon (EGD) 가 한가지 방법으로 이는 시스템 활동을 감시해 이를 임의적으로 값으로 해시한다; 이는 http://www.lothar.com/tech/crypto 에서 얻을 수 있다. PRNG 출력에 암호화 해시 함수 (예, SHA-1) 의 사용을 고려할 수도 있는데 해시 알고리듬을 사용함으로써 PRNG 가 예측가능하다고 판명되었음에도 불구하고 이는 공격자가 또한 해시 함수도 해독해야 한다는 것을 의미한다.

강력한 PRNG 를 스스로 구현해야 한다면 암호학적으로 강력하며 특허에 얽매이지 않은 PRNG 의 좋은 선택은 Yarrow 알고리듬으로 http://www.counterpane.com/yarrow.html. 에서 Yarrow 에 대해 더욱 자세히 알 수 있다. 약간의 다른 PRNG 도 유용할 수 있지만 널리 사용되고 있는 많은 PRNG 은 애플리케이션에 따라 중요하거나 그렇지 않을 수도 있는 알려진 약점을 갖고 있다. PRNG 를 스스로 구현하기 전에 [Kersey 1998] 과 McGraw [2000a] 와 같은 문헌을 참조해라. 또한IETF RFC 1750 도 조사해야 한다.