[Java] Random vs SecureRandom 무엇을 사용해야 하나?

컴투루·2023년 2월 1일
0

Java

목록 보기
4/4

쿠폰 seqNumber를 생성할 때 Random클래스를 사용하고 있었는데 Random보다는 SecureRandom을 사용하라고 취약점 리스트에 올라왔다.

디버깅을 해보니 두 개의 값이 서로 같아서 일단은 SecureRandom으로 수정을 했다. 근데 생각해보니 왜...? 어디가 취약하다는거지...? 의문이 생겨서 알아보기로 했다.


📌 Random은 안전하지 않다.

Random함수도 난수를 생성하지만 진짜 난수가 아닌 난수처럼 보이는 알고리즘을 통한 규칙적인 난수만 생성한다...?

이건 또 무슨 소리일까

컴퓨터는 기본적으로 정해진 입력에 따라 정해진 값만 내보낼 수 있는데 따라서 생성된 랜덤값은 정말로 임의의 값이 아니고 특정한 벙법으로 여러 계산을 거쳐서 사람이 볼 때 마치 임의의 값처럼 보이게 하는 의사난수(Pseudo Random)라고 한다.

이를 해결하기 위해서는 난수표를 여러개 만들어 놓고 매번 다른 난수표를 읽도록 해야하는데 여기서 난수표를 선택하는것을 '시드'라고 한다.

그런데 시드값이 같으면 선택되는 난수표도 똑같기 때문에 시드값도 난수여야하는 문제가 발생하게 되고 결국 난수를 만들려면 난수가 필요한 문제가 발생하게 된다.

즉, 시드값이 동일하면 매번 같은 값을 보여주는 것이다.

이젠 Random이 어느 부분에서 취약한지 알게 되었다.

그렇다면 SecureRandom은 Random과 다르게 안전한지 알아보자.


📌 Random vs SecureRandom

  1. 크기
    Random은 48비트, SecureRandom은 최대 128비트를 포함 할 수 있기 때문에 SecureRandom에서 반복 가능성이 더 낮아진다.

  2. 시드 생성
    Random은 시스템 시간을 시드로 사용하거나 생성하기 때문에 공격자가 생성 시간말 알고 있으면 재현이 가능하다.
    SecureRandom은 OS에서 임의의 데이터를 가져와서 시드로 사용한다.

  3. 코드 깨기
    Random은 고급 CPU를 사용하면 2^48번의 시도만에 깨뜨릴수 있지만 SecureRandom은 2^128번의 시도가 필요하고 오랜시간이 걸린다.

  4. 보안
    SecureRandom은 FIPS 140-2(암호학에서 사용되는 생성기표준)에서 지정한 테스트를 준수하기 때문에 좀 더 안전하고 SHA1PRNG를 사용하기 때문에 좀 더 안전한 알고리즘을 구현한다.


📌 SecureRandom은 안전한건가?

SecureRandom.getInstanceStrong()은 디폴트로 /dev/random에서 시드값을 얻어온다. 이로인해서 자바 버그로 인해 엄청난 퍼포먼스 저하를 발생시킬수 있다...
따라서 별도의 경로를 설정해주어야한다.

결국 SecureRandom도 Random에 비해 오버헤드와 경합이 적을 뿐 암호학적으로 안전하지 않다.


📒참고

자바의 난수생성기 Random, SecureRandom
[Java] Random보단 SecureRandom 를 사용하자.

profile
맘 먹으면 못할 게 없지

0개의 댓글