❓ 서론
Random 을 사용하다가 생긴 버그로 고쳐본 경험..
그 후 알아본 내용을 정리한다.
본론
에러 메세지
“Random” objects should be reused
“Random" 객체는 재 사용 되어야 한다.
Random 값이 필요할 때 마다 새 개체를 만드는 것은 비효율적이며
JDK에 따라 임의의 숫자가 생성되지 않을 수 있다.
효율성과 임의성을 높이려면 단일 Random을 만든 다음 저장하고 다시 사용한다.
Random() 생성자는 별개의 값마다에 seed를 설정하려고 시도합니다.
그러나 일부 JDK는 현재 시간을 seed로 사용하므로 생성 된 숫자가 전혀 무작위가 아닙니다.
public void noRandom() {
Random rand = new Random(); // 매번 새 개체를 만드는 방식.. 비 효율적
int rValue = rand.nextInt();
//...
}
private Random rand = SecureRandom.getInstanceStrong(); // SecureRandom이 선호된다.
public void yesRandom() {
int rValue = rand.nextInt();
//...
}
1️⃣ Why not use Random?
기본적으로 Random 함수를 사용하는 목적은 난수를 생성하기 위함이다.
하지만, 우리가 생각했던 것 처럼 정말 무작위로 생성되는 것이 아닌
‘의사난수’ 가 생성되는 것이다.
의사난수?
‘의사난수’란 난수처럼 보이게 하기 위해 어떠한 알고리즘을 이용해 규칙적인 난수를 생성하는 것을 의미한다.
결론적으로 완전한 난수가 아닌 규칙적으로 만들어진 난수처럼 보이는 값이라는 것
Random은 의사난수?
Random을 생성하기 위해선 seed(기준이 되는 값)을 세팅해준다.
Random rand = new Random(); // seed = System.nanoTime();
값을 넣지 않으면 시스템 시간을 통해 값을 세팅 하고 이를 통해 Random값을 규칙적으로 만든다.
이는 세팅 된 값이 동일하다면 매번 같은 값을 보여줄 것이다.
만약 비밀번호 같이 보안에서 사용되는 난수를 만들기 위해 Random을 사용하게 된다면
이는 적합하지 않다.
JAVA 7 API DOCS - Random
Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance. Consider instead using ThreadLocalRandom in multithreaded designs.
Instances of java.util.Random are not cryptographically secure. Consider instead using SecureRandom to get a cryptographically secure pseudo-random number generator for use by security-sensitive applications.
2️⃣ So is SecureRandom different?
DIVISION | Random | SecureRandom |
---|---|---|
SIZE | only 48 bit | max 128 bit |
MADE SEED | SYSTEM.TIME | OS.TEMPDATA |
BROKEN | 2 ^ 48 | 2^ 128 |
CREATION FUNCTION | Linear Congruential Generator | SHA1PRNG Algorithm |
3️⃣ Are there any SecureRandom problems?
SecureRandom.getInstanceStrong() 에서는 디폴트로 /dev/random 디렉토리에서 시드 값을 얻어온다.
이는 자바 버그로 인해 엄청난 퍼포먼스 저하를 발생할 수 있다.
new SecureRandom()을 사용하게 되면, /dev/urandom 를 호출하게 되어 이 퍼포먼스 저하를 방지할 수 있다.
결론
Random을 매번 생성하지 말고, SecureRandom 을 사용하여 한 번만 호출해서 사용할 수 있다.
비밀번호 등 민감성 데이터를 암호화 해야할 때는 SecureRandom을 사용하자.
Reference
https://st-lab.tistory.com/76
https://github.com/ksundong/TIL/blob/master/Java/Difference-with-SecureRandom-and-Random.md
https://www.geeksforgeeks.org/random-vs-secure-random-numbers-java/
https://stackoverflow.com/questions/295628/securerandom-init-once-or-every-time-it-is-needed
https://github.com/pravusid/TIL/blob/master/Security/secure-random.md
https://blog.eomsh.com/37
https://developmentlee.tistory.com/31
https://lng1982.tistory.com/261
https://gampol.tistory.com/entry/Tomcat-%EA%B5%AC%EB%8F%99-%EC%8B%9C-devurandom-%EB%B8%94%EB%A1%9C%ED%82%B9-%EC%9D%B4%EC%8A%88%EC%A7%80%EC%97%B0%EC%8B%9C%EC%9E%91-%EB%AC%B8%EC%A0%9C
https://kdhyo98.tistory.com/m/48
notion에서 보기