Notice
Recent Posts
Recent Comments
Link
IgnatiusHeo
구현단계 보안약점 제거 기준-적절하지 않은 난수 값 사용 본문
작성일: 230704
※ 본 게시글은 학습 목적으로 행정안전부·KISA의 소프트웨어 보안약점 진단 가이드, 소프트웨어 개발보안 가이드를 참고하여 작성하였습니다.
정리 내용: 소프트웨어 보안약점 진단 가이드(364~369p)
구분 | - 보안기능 |
설계단계 | - 암호연산 https://cryptocurrencyclub.tistory.com/105 |
개요 | 예측 가능한 난수를 사용하는 것은 시스템에 보안약점을 유발한다. 예측 불가능한 숫자가 필요한 상황에서 예측 가능한 난수를 사용한다면, 공격자는 SW에서 생성되는 다음 숫자를 예상하여 시스템을 공격하는 것이 가능하다. |
진단 세부사항 (설계단계) |
① 대칭키 또는 비대칭키를 이용해서 암복호화를 수행해야 하는 경우 KISA의 암호이용안내서에서 정의하고 있는 암호화 알고리즘과 안전성이 보장되는 암호키 길이를 사용해야 한다. ㅇ 암복호화 기능 설계 시 안전한 암호 알고리즘을 사용하도록 설계되었는지 확인 - 대칭키: SEED, ARIA, AES 등 - 비대칭키: RSA, KCDSA, ECC 등 ㅇ 암복호화 기능 설계 시 안전한 암호키 길이를 사용하도록 설계되었는지 확인 - 대칭키: 128bit 이상 - 비대칭키: 2048bit 이상 ② 복호화되지 않는 암호화를 수행하기 위해 해시함수를 사용하는 경우 안전한 해시 알고리즘과 솔트값을 적용하여 암호화해야 한다. ㅇ 복호화되지 않는 암호화 기능설계시 안전한 암호화 알고리즘을 사용하도록 설계되어 있는지 확인 - ex)SHA-2 (SHA-3는 왜 안보일까?) ㅇ 해시함수의 보안을 강화하기 위해 솔트값(난수발생기를 이용해 생성한 안전한 난수값)을 사용하여 암호화하도록 설계되어 있는지 확인 ③ 난수 생성 시 안전한 난수 생성 알고리즘을 사용해야 한다. ㅇ 개발가이드에 안전한 난수 생성알고리즘을 사용하도록 코딩규칙을 정의하고 있는지 확인 - JAVA: java.security.SecureRandom, java.util.Random - C: randomize(seed) |
보안대책 (구현단계) |
컴퓨터의 난수발생기는 난수 값을 결정하는 시드(Seed)값이 고정될 경우, 매번 동일한 난수값이 발생한다. 이를 최대한 피하기 위해 Java에서는 Random()과 Math.random() 사용 시 java.util.Random 클래스에서 기본값으로 현재시간을 기반으로 조합하여 매번 변경 되는 시드(Seed)값을 사용하며, C에서는 rand()함수 사용 시 매번 변경되는 기본 시드(Seed)값이 없으므로, srand()로 매번 변경되는 현재시간 기반 등으로 시드(Seed)값을 설정 하여야 한다. 그러나 세션 ID, 암호화키 등 보안결정을 위한 값을 생성하고 보안결정을 수행하는 경우에는, Java에서 Random()과 Math.random()을 사용하지 말아야 하며, 예측이 거의 불가능하게 암호학적으로 보호된 java.security.SecureRandom 클래스를 사용하는 것이 안전하다. |
진단방법 (구현단계) |
① Math.random() 메소드를 사용하는지 확인한다. Math.random()을 사용하는 경우 취약하다. ② 난수값을 세션ID로 설정하여 보안결정에 사용하는지 확인한다. 보안 결정인 경우 java.security.SecureRandom을 사용하면 안전하다. |
다. 코드예제
ㅇ 분석
1: import java.util.Random;
2: ...
3: public Static int getRandomValue(int maxValue) {
//고정된 시드값을 사용하여 동일한 난수값이 생성되어 안전하지 않다.
4: Random random = new Random(100);
5: return random.nextInt(maxValue);
6: }
7: public Static String getAuthKey() {
//매번 변경되는 시드값을 사용하여 다른 난수값이 생성되나 보안결정을 위한 난수로는
안전하지 않다.
8: Random random = new Random();
9: String authKey = Integer.toString(random.nextInt());
ㅇ 내용
1. r4에서는 시드값이 고정이고
2. r8에서는 시드값을 안넣었어서 랜덤으로 생성이 가능하나 보안결정을 위한 난수로는 안전하지 않다함.
ㅇ 수정
1: import java.util.Random;
2: import java.security.SecureRandom;
3: ...
4: public Static int getRandomValue(int maxValue) {
//setSeed로 매번 변경되는 시드값을 설정 하거나, 기본값인 현재 시간 기반으로 매번
변경되는 시드값을 사용하도록 한다.
5: Random random = new Random();
6: return random.nextInt(maxValue);
7: }
8: public Static String getAuthKey() {
//보안결정을 위한 난수로는 예측이 거의 불가능하게 암호학적으로 보호된 SecureRandom을
사용한다.
9: try{
10: SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
11: MessageDigest digest = MessageDigest.getInstance("SHA-256");
12: secureRandom.setSeed(secureRandom.generateSeed(128));
13: String authKey = new String(digest.digest((secureRandom.nextLong() + "").getBytes()));
14: ...
15: } catch (NoSuchAlgorithmException e) {
ㅇ 내용
1. 랜덤값 받는 함수에서는 시드값을 랜덤으로 설정해놓고
2. 보안결정에 사용하는거는 CSPRNG사용함.
ㅇ 분석
1: static int GenerateDigit()
2: {
//매번 변경되는 시드값을 사용하여 다른 난수값이 생성되나 보안결정을 위한
난수로는 안전하지 않다.
3: Random rng = new Random();
4: return rng.Next(10);
5: }
ㅇ 내용
1. 아니 근데 이게 보안결정용인지 단순 용도인지는 어떻게 구분함?
ㅇ 수정
1: static int GenerateDigitGood()
2: {
//보안결정을 위한 난수로는 예측이 거의 불가능하게 암호학적으로 보호된
SecureRandom을 사용한다.
3: byte[] b = new byte[4];
4: new
System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(b);
5: return (b[0] & 0x7f) << 24 | b[1] << 16 | b[2] << 8 | b[3];
6: }
ㅇ 내용
1. 그냥 다 CSPRNG 쓰자
ㅇ 분석
1: void foo(){
2: int i;
3: for(i=0; i<20; i++)
// 프로그램을 여러 번 실행 했을 때 얻는 결과 값이 같다. 범위가 작기 때문에
암호화에 사용되기 힘들다.
4: printf("%d", rand());
ㅇ 내용
1. rand의 RNG 시퀀스가 동일하게 반복될 수 있으므로 사용하기 어려움(rand의 디폴트 시드는 1임)
ㅇ 수정
1: void foo(){
2: srandom(time(NULL));
3: int i;
4: for(i=0; i<20; i++)
5: printf("%ld", random());
6: }
ㅇ 내용
1. srandom을 이용해 시드값을 현재시간으로 선정해서 랜덤값에 대한 RNG가 가능함
끝.
'자격 > SW보안약점진단원' 카테고리의 다른 글
구현단계 보안약점 제거 기준-부적절한 전자서명 확인 (0) | 2023.07.04 |
---|---|
구현단계 보안약점 제거 기준-취약한 비밀번호 허용 (0) | 2023.07.04 |
구현단계 보안약점 제거 기준-충분하지 않은 키 길이 사용 (0) | 2023.07.04 |
구현단계 보안약점 제거 기준-하드코드된 중요정보 (0) | 2023.07.04 |
구현단계 보안약점 제거 기준-암호화되지 않은 중요정보 (0) | 2023.07.04 |