[Java/Short] SecureRandom을 이용한 랜덤 숫자/문자(난수) 생성 방법
해당 글에서는 Math 함수가 아닌 SecureRandom 함수를 이용하여 랜덤 한 숫자/문자(난수) 생성방법에 대해 알아봅니다.
1) Math.random() 함수를 사용하지 않는 이유
💡 Random 함수를 사용하지 않는 이유
- SonarQube를 통해서 Security Hotspots로 Math.random() 함수에서 아래와 같은 문제점이 발생하였습니다.
- 여기에서 이 의사 난수 생성기를 사용하는 것이 안전한지 확인하세요.(Make sure that using this pseudorandom number generator is safe here.)
- 해당 문제는 ‘난수 생성‘에 대해 보안에 민감하다는 문제점이 발생합니다. 이는 Math.random() 역시 난수를 생성하는 데 있어서 보안적으로 취약점이 있다는 문제점이 발생하였습니다.

💡 [참고] 또한 Math.random() 함수를 사용하면 안되는 이유
Why do not use Math.random()
The JavaScript Math.random() function is designed to return a floating point value between 0 and 1. It is widely known (or at least should…
kemilbeltre.medium.com
💡 [참고] Math.random()관련 취약점 관련 글
[RN/오류노트] Math.random() 취약점에 대한 해결방법 : Make sure that using this pseudorandom number generator is sa
해당 글에서는 Math.random() 함수를 사용하였을 때 Weak Cryptography 보안 취약점 문제가 발생함에 따라 이를 해결하는 방법에 대해 확인해 봅니다. 1) 문제점 💡 문제점 - SonarQube로 React-native를 수행하
adjh54.tistory.com
💡 [참고] SecureRandom API Document
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
2) 랜덤 숫자 생성
1. 자릿수 만큼 랜덤 숫자 생성
public class CommonUtils {
/**
* 자릿수(digit) 만큼 랜덤한 숫자를 반환 받습니다.
*
* @param length 자릿수
* @return 랜덤한 숫자
*/
public static int generateRandomNum(int length) {
SecureRandom secureRandom = new SecureRandom();
int upperLimit = (int) Math.pow(10, length);
return secureRandom.nextInt(upperLimit);
}
}
int randomNum = CommonUtils.generateRandomNum(6); // 894625
2. 시작 범위와 종료 범위의 랜덤 숫자(난수) 생성
public class CommonUtils {
/**
* 시작 범위(start)와 종료 범위(end) 값을 받아서 랜덤한 숫자를 반환 받습니다.
*
* @param start 시작 범위
* @param end 종료 범위
* @return 랜덤한 숫자
*/
public static int generateRangeRandomNum(int start, int end) {
SecureRandom secureRandom = new SecureRandom();
return start + secureRandom.nextInt(end + 1);
}
}
int rangeRandomNum = CommonUtils.generateRangeRandomNum(1, 1000); // 644
3) 랜덤 문자 생성
1. 자릿수 만큼 랜덤 대문자/소문자 생성
public class CommonUtils {
/**
* 자릿수(length) 만큼 랜덤한 문자열을 대문자/소문자에 따라 반환 받습니다.
*
* @param length 자릿수
* @param isUpperCase 대문자 여부
* @return 랜덤한 문자열
*/
public static String generateRandomStr(int length, boolean isUpperCase) {
String alphabet = "abcdefghijklmnopqrstuvwxyz";
SecureRandom secureRandom = new SecureRandom();
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(alphabet.charAt(secureRandom.nextInt(alphabet.length())));
}
return isUpperCase ? sb.toString().toUpperCase() : sb.toString().toLowerCase();
}
}
String randomStr = CommonUtils.generateRandomStr(5, true); // EJQOM
4) 랜덤 숫자 + 문자 조합 생성
1. 자릿수 만큼 랜덤 숫자 + 대문자/소문자 생성
public class CommonUtils {
/**
* 자릿수(length) 만큼 랜덤한 숫자 + 문자 조합을 대문자/소문자에 따라 반환 받습니다.
*
* @param length 자릿수
* @param isUpperCase 대문자 여부
* @return 랜덤한 숫자 + 문자 조합의 문자열
*/
public static String generateRandomMixStr(int length, boolean isUpperCase) {
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
SecureRandom random = new SecureRandom();
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int index = random.nextInt(characters.length());
sb.append(characters.charAt(index));
}
return isUpperCase ? sb.toString() : sb.toString().toLowerCase();
}
}
String randomMixStr = CommonUtils.generateRandomMixStr(10, true); // II9H2J0VIF
5) 종합
import java.security.SecureRandom;
/**
* 공통 유틸
*
* @author : lee
* @fileName : CommonUtils
* @since : 1/22/24
*/
public class CommonUtils {
private CommonUtils() {
}
/**
* 자릿수(digit) 만큼 랜덤한 숫자를 반환 받습니다.
*
* @param length 자릿수
* @return 랜덤한 숫자
*/
public static int generateRandomNum(int length) {
SecureRandom secureRandom = new SecureRandom();
int upperLimit = (int) Math.pow(10, length);
return secureRandom.nextInt(upperLimit);
}
/**
* 시작 범위(start)와 종료 범위(end) 값을 받아서 랜덤한 숫자를 반환 받습니다.
*
* @param start 시작 범위
* @param end 종료 범위
* @return 랜덤한 숫자
*/
public static int generateRangeRandomNum(int start, int end) {
SecureRandom secureRandom = new SecureRandom();
return start + secureRandom.nextInt(end + 1);
}
/**
* 자릿수(length) 만큼 랜덤한 문자열을 대문자/소문자에 따라 반환 받습니다.
*
* @param length 자릿수
* @param isUpperCase 대문자 여부
* @return 랜덤한 문자열
*/
public static String generateRandomStr(int length, boolean isUpperCase) {
String alphabet = "abcdefghijklmnopqrstuvwxyz";
SecureRandom secureRandom = new SecureRandom();
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(alphabet.charAt(secureRandom.nextInt(alphabet.length())));
}
return isUpperCase ? sb.toString().toUpperCase() : sb.toString().toLowerCase();
}
/**
* 자릿수(length) 만큼 랜덤한 숫자 + 문자 조합을 대문자/소문자에 따라 반환 받습니다.
*
* @param length 자릿수
* @param isUpperCase 대문자 여부
* @return 랜덤한 숫자 + 문자 조합의 문자열
*/
public static String generateRandomMixStr(int length, boolean isUpperCase) {
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
SecureRandom random = new SecureRandom();
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int index = random.nextInt(characters.length());
sb.append(characters.charAt(index));
}
return isUpperCase ? sb.toString() : sb.toString().toLowerCase();
}
}
💡 [참고] 숫자 + 특수문자, 문자 + 특수문자, 숫자 + 문자 + 특수문자 혹은 임시비밀번호로 사용되는 형태의 랜덤 문자열에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
[Java/Short] SecureRandom을 이용한 랜덤 문자열 생성 방법: 숫자, 문자, 특수문자 조합, 임시 비밀번호
해당 글에서는 SecureRandom 클래스를 사용하여서 랜덤 문자열을 생성하는 방법에 대해 알아봅니다. 또한 임시 비밀번호로 이용할 수 있는 방법에 대해서도 알아봅니다. 1) SecureRandom을 이용한 랜덤
adjh54.tistory.com
오늘도 감사합니다. 😀