JavaScript에서 난수 생성은 여러 용도로 사용됩니다. 하지만 Math.random() 함수를 사용할 경우 보안 취약점이 발생할 수 있습니다. 본 글에서는 이 문제를 살펴보고 어떻게 해결할 수 있는지에 대해 알아보겠습니다.
문제점
Math.random()의 보안 취약점
Math.random() 함수는 0과 1 사이의 부동 소수점 값을 생성합니다. 이 함수는 사용하기 간편하지만, 보안적으로 안전하지 않은 난수를 생성하는 경향이 있습니다. SonarQube를 통해 React Native 프로젝트에서 확인된 바에 따르면, Math.random()의 사용은 보안 핫스팟으로 지적되었습니다. 이는 난수 생성이 보안에 민감한 작업임을 강조합니다.
- 위험 요소: Math.random()은 예측 가능한 난수를 생성할 수 있어, 공격자가 이를 이용하여 시스템에 침투할 가능성이 존재합니다.
- 보안 인프라의 필요성: 암호화 및 보안이 중요한 애플리케이션에서는 Math.random()의 사용을 피해야 합니다.
해결방법
expo-crypto 라이브러리 사용
Math.random() 대신 expo-crypto 라이브러리를 사용하여 보다 안전한 난수를 생성할 수 있습니다. 이 라이브러리는 암호학적으로 안전한 난수를 생성하는 Crypto.getRandomValues() 함수를 제공합니다.
-
expo-crypto 설치
bash
npm install expo-crypto
또는
bash
yarn add expo-crypto -
Crypto.getRandomValues() 함수 활용
이 함수는 암호학적으로 강력한 난수를 생성하며, 매개변수로 제공된 배열을 무작위 숫자로 채웁니다. 아래는 이를 활용한 난수 생성기 구현 예제입니다.
“`javascript
import * as Crypto from ‘expo-crypto’;
class CommonUtil {
makeCrpytoRandomNum = (): number => {
const randomBuffer = new Uint32Array(1);
Crypto.getRandomValues(randomBuffer);
return randomBuffer[0] / (0xffffffff + 1);
}
generateRandomNum = (min: number, max: number): number => {
const randomNum = this.makeCrpytoRandomNum();
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(randomNum * (max - min + 1)) + min;
};
}
“`
구현 설명
- randomBuffer 생성: Uint32Array 배열을 생성하여 32비트 정수를 저장합니다.
- 난수 채우기: Crypto.getRandomValues(randomBuffer)를 호출하여 randomBuffer를 암호학적으로 안전한 난수로 채웁니다.
- 난수 반환: randomBuffer[0]을 사용하여 0과 1 사이의 난수 값을 반환합니다. 이 값을 바탕으로 최소값과 최대값 사이의 난수를 생성합니다.
기타 대분류들
대안 라이브러리
Math.random() 대신 사용할 수 있는 다른 라이브러리로는 Crypto-js나 react-native-crypto가 있습니다. 이러한 라이브러리도 암호학적으로 안전한 난수를 생성하는 데 유용합니다.
자주 묻는 질문
Math.random()은 왜 사용하면 안 되나요?
Math.random()은 예측 가능한 난수를 생성할 수 있어 보안에 취약합니다. 보안이 중요한 애플리케이션에서는 이를 사용하지 않는 것이 좋습니다.
expo-crypto 라이브러리는 어떻게 설치하나요?
npm 또는 yarn을 사용하여 expo-crypto를 설치할 수 있습니다. 설치 후, Crypto.getRandomValues() 함수를 활용하여 안전한 난수를 생성할 수 있습니다.
다른 언어에서도 비슷한 문제가 발생하나요?
Java에서도 비슷한 문제가 발생할 수 있으며, 이 경우에는 “Random” 객체를 재사용해야 한다는 경고가 나타날 수 있습니다. 이를 해결하기 위해 객체를 재사용하는 방식으로 코드를 작성해야 합니다.
