본문 바로가기
DEV/JAVA

[JAVA] 올바르지 않은 난수 취약점(Math.random) 해결 방법

by 무사뎀벨레 2024. 11. 25.

 

 

 

 

 

 

 

Math클래스의 random함수 취약점


JAVA의 내장 클래스인 Math클래스의 random 함수는 0.0 ~ 1 사이의 더블(double) 유형의 숫자를 반환하는 메서드이다.

보통 0부터 99 사이의 난수를 추출하기 위해 아래와 같이 코드로 구현할 수 있다.

(int)(Math.random() * 100);

 

하지만, Math클래스의 random 함수의 사용은 예상가능한 난수를 사용하는 것으로 시스템 보안에 약점을 유발한다고 한다.

Math클래스의 random 함수는 시드값을 설정할 수 없고, 사용하는 알고리즘이 밝혀지면 취약해질 수 있기 때문이다.

 

random이라는 단어의 뜻처럼 무작위로 생성하는 것이 아니라 난수처럼 보이게 하기 위해 어떠한 알고리즘을 사용한 규칙적인 난수를 생성하는 것을 뜻하는 '의사난수'를 생성하는 것이다.

 

결론적으로 Math클래스의 random 함수는 정말로 난수가 아닌 규칙적으로 만들어진 난수처럼 보이는 값을 생성하는 문제가 발생하는 것이다.

 

 

 

 

 

 

 

Math클래스의 random함수 취약점 해결 방법


Math클래스의 random 함수를 사용함으로써 발생되는 취약점은 JAVA의 내장 클래스인 SecureRandom클래스를 사용함으로서 해결할 수 있다. JAVA에서 SecureRandom를 아래 링크와 같이 설명하고 있다.

https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html

 

SecureRandom (Java Platform SE 8 )

This class provides a cryptographically strong random number generator (RNG). A cryptographically strong random number minimally complies with the statistical random number generator tests specified in FIPS 140-2, Security Requirements for Cryptographic Mo

docs.oracle.com

 

 

 

random 함수와 SecureRandom함수를 비교하면 아래와 같이 정리할 수 있다.

https://www.geeksforgeeks.org/random-vs-secure-random-numbers-java/

 

Random vs Secure Random numbers in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

1. 크기

- Random함수에는 48 비트만 있는 반면, SecureRandom은 최대 128 비트를 포함할 수 있다. 그렇기 때문에 SecureRandom에서 반복할 가능성은 더 적다.

 

2. 시드 생성

- Random은 시스템 시간을 시드로 사용하거나 시드를 생성한다. 따라서 공격자가 시드가 생성된 시간을 알고 있으면 쉽게 재현할 수 있다. 그러나 SecureRandom은 OS에서 임의 데이터를 가져와서 이를 시드로 사용한다.

 

3. 코드 깨기(Breaking the code)

- Random의 경우 2 ^ 48번만 시도하면 되며 오늘날의 고급 CPU를 사용하면 실제 시간에 깨뜨릴 수 있다. 그러나 SecureRandom을 위해서는 2 ^ 128번의 시도가 필요하며, 오늘날의 고급 기계에서도 중단되려면 몇 년이 걸릴 것이다.

 

4. 생성 기능

- 표준 Oracle JDK 7 구현은 Linear Congruential Generator를 사용하여 java.util.Random에서 임의의 값을 생성한다. Secure Random은 SHA1을 사용하여 의사 난수를 생성하는 SHA1PRNG 알고리즘을 구현한다. 알고리즘은 진정한 난수에 대해 SHA-1 해시를 계산 한 다음 각 작업에서 1 씩 증가하는 64 비트 카운터와 연결한다.

 

5. 보안

- 결과적으로 java.util.Random이 중요한 응용 프로그램이나 중요한 데이터를 보호하기 위해 랜덤 클래스를 사용해서는 안된다.

 

 

random 함수와 SecureRandom함수의 구현 방법은 아래와 같다.

// Math.random()
int div = (int) Math.floor( Math.random() * 2 );

// SecureRandom()
SecureRandom sr = new SecureRandom();
int div = sr.nextInt(2);
반응형

댓글