소프트웨어 개발보안 가이드 분석(2021) : 적절하지 않은 난수값 사용

취약점에 대한 이해

소프트웨어 및 애플리케이션 개발에서 난수(random numbers)의 사용은 다양한 목적으로 이루어집니다. 예를 들어, 세션 식별자 생성, 토큰 발급, 암호화 키 생성 등 보안에 중요한 요소들의 생성에 난수가 사용됩니다. 이러한 용도로 사용되는 난수는 예측이 불가능해야 하며, 암호학적으로 안전해야 합니다. 즉, 난수가 높은 수준의 무작위성을 가져야 하며, 외부에서 그 패턴을 예측할 수 없어야 합니다.

소프트웨어개발보안가이드(한국인터넷진흥원, 2021)

위 이미지는 난수 생성과 관련된 보안 취약점을 설명하고 있습니다. 좌측 부분에서 java.Math.random()을 사용하여 생성된 난수들은 예측 가능한 패턴을 보이고 있습니다. 이러한 패턴을 통해 해커가 시스템의 난수 생성 패턴을 분석하여 결국 예측 가능한 값을 찾아내는 것을 나타내고 있습니다.

반면에, 우측 부분에서는 java.util.Random 또는 java.security.SecureRandom을 사용하여 생성된 난수들이 표시되어 있습니다. 이 난수들은 예측할 수 없으므로, 해커는 결과를 추측할 수 없음을 나타내고 있습니다. 전반적으로, 이 이미지는 암호학적으로 안전하지 않은 난수 생성 방식이 어떻게 보안 위협이 될 수 있는지, 그리고 암호학적으로 안전한 난수 생성기의 중요성을 시각적으로 보여주고 있습니다.

 

문제점

난수 생성의 중요성은 주로 보안 측면에서 강조됩니다. 보안에 취약한 난수 생성기를 사용하는 경우, 다음과 같은 위험에 노출될 수 있습니다.

세션 하이재킹: 공격자가 세션 ID를 예측하여 사용자의 세션을 빼앗을 수 있습니다.

토큰 기반 시스템의 취약성: 예측 가능한 토큰 값은 공격자에게 시스템 내부에 접근할 수 있는 키를 제공할 수 있습니다.

암호화 키의 약화: 암호화 키 생성에 사용된 난수가 예측 가능하다면, 해당 키를 통해 보호되는 데이터는 더 이상 안전하지

과거 IoT 기기의 하드웨어 난수 생성기가 임의의 숫자를 적절히 생성하지 못하여 보안에 중대한 위험을 초래하는 취약점이 발견된 바 있습니다.(thehackernews.com, 2021).

 

해결책

난수 생성의 복잡성은 주로 난수 생성 알고리즘의 선택에서 비롯됩니다. 모든 난수 생성기가 동일하게 만들어지는 것은 아니며, 일부는 암호학적으로 안전하지 않은 난수를 생성할 수 있습니다. 이러한 난수 생성기는 주로 패턴이 예측 가능하거나, 충분한 무작위성을 제공하지 못할 수 있습니다. 따라서, 보안 목적으로 난수를 생성할 때는 암호학적으로 안전한 난수 생성기(Cryptographically Secure Pseudorandom Number Generator, CSPRNG)를 선택하는 것이 중요합니다.

암호학적으로 안전한 난수 생성기는 고급 암호학 원리를 기반으로 하여, 공격자가 예측할 수 없는 난수를 제공합니다. 이러한 난수는 통계적 검사뿐만 아니라, 암호학적 속성을 충족시켜야 하며, 심지어 초기 조건(예: 시드 값)이 공개되더라도 결과를 예측하기 어렵게 설계되어야 합니다. 이러한 배경 지식을 바탕으로, 소프트웨어 및 애플리케이션 개발에서 적절하지 않은 난수값의 사용은 심각한 보안 취약점으로 이어질 수 있으며, 개발자는 암호학적으로 안전한 난수 생성 방법을 적극적으로 활용해야 합니다. 이는 보안 강화뿐만 아니라, 사용자의 신뢰 획득 및 유지에도 기여할 것입니다.

 

취약한 코드와 안전한 코드 예제

import java.util.Random;
...
Random random = new Random(100); // 고정된 시드값 사용
int value = random.nextInt();

안전하지 않은 코드 예제: java.util.Random을 사용하여 난수를 생성하는 경우, 고정된 시드값으로 인해 예측 가능한 값을 생성할 수 있습니다.

 

import java.security.SecureRandom;
...
SecureRandom secureRandom = new SecureRandom();
int value = secureRandom.nextInt();

안전한 코드 예제: java.security.SecureRandom을 사용하여 난수를 생성하는 경우, 예측 불가능한 안전한 난수값을 얻을 수 있습니다.

 

※ 참고자료

  1. CWE-330: Use of Insufficiently Random Values, MITRE.
  2. Generate strong random numbers, CERT.
  3. Do not use the rand() function for generating pseudorandom numbers, CERT.
  4. Insecure Randomness, OWASP.

  • 이전 소프트웨어 개발보안 가이드 분석(2021) : 충분하지 않은 키 길이 사용
  • 다음 소프트웨어 개발보안 가이드 분석(2021) : 취약한 비밀번호 허용