Java/Short 개발

[Java/Short] SecureRandom을 이용한 랜덤 숫자/문자(난수) 생성 방법

adjh54 2024. 1. 22. 18:02
728x170

 

해당 글에서는 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

 


 
 
오늘도 감사합니다. 😀
 
 
 

그리드형