주어진 배열의 합계를 구하는 알고리즘을 작성해봤다!

public static int arraySum(int[] array) {
		return arraySumRecur(array, array.length);
	}

	public static int arraySumRecur(int[] array, int idx) {
		if (idx <= 0) {
			return 0;
		} else {
			return arraySumRecur(array, idx - 1) + array[idx - 1];
		}
	}

'알고리즘 & 기능' 카테고리의 다른 글

Fractal 연습해보기!  (0) 2020.11.04
Math.pow() 함수 직접 구현해보기!  (0) 2020.11.04

 

프랙탈 알고리즘을 연습해보자 ! 

주어진 문제는 Junit에서 테스트 코드로 해당 함수를 호출했을때 정상적으로 프랙탈이 그려질 수 있도록 

알고리즘을 짜는 것이었다. 

매가값 n 만큼 늘어나야하는데 

1씩 증가할때마다

F => F-H 가 되어야하고 

H => F+H가 되어야한다. 

만들어진 문구 F, H는 앞으로 나가는 방향을 의미하고 

+ 는 시계방향으로 90도 회전 

-  는 반시계방향으로 90회전한다. 

단,

메서드를 추가해서는 안되고 하나의 메소드로 해결해야하며 

loop 를 사용할 수 없다.

 

예_

// myFractal(0) = F-H
// myFractal(1) = F-H-F+H
// myFractal(2) = F-H-F+H-F-H+F+H
// myFractal(3) = F-H-F+H-F-H+F+H-F-H-F+H+F-H+F+H

public static String myFractal(int n) {
		
		// myFractal(0) = F-H
		// myFractal(1) = F-H-F+H
		// myFractal(2) = F-H-F+H-F-H+F+H
		// myFractal(3) = F-H-F+H-F-H+F+H-F-H-F+H+F-H+F+H

		if (n == 0) {
			return "F-H";
		}

		return myFractal(n-1).replaceAll("H", "D").replaceAll("F", "F-H").replace("D", "F+H");
}

 

답) 

우선 입력받은 n 번 만큼 반복되어야 하기 때문에 (n-1) 이 되어야겠다.~ 라고 생각했다. 

loop와 추가 메소드를 사용할 수 없기에 재귀호출이 되어야겠다고 생각했고 myFractal(n-1) 이 나왔다! 

if문을 사용해 재귀호출에 break 를 걸어주는 부분을 만들었고 

replaceAll() 함수를 이용해 문자를 변경하려고 했다. 

그런데 F를 F-H로 변경하고 H를 다시 F+H로 변경하려고 보니 변경된 문자를 다시 변경하게되는 이슈가 있었다.

그래서 H를 D로 변경해둔 뒤 F변경하고 D를 F+H로 변경하는 방법으로 구현했다!

 

흠!! 잘 나온다 성공! 

 

기존에 운영중인 서비스에 적용된 암호화 알고리즘이 취약하다는 결과를 받았다.

 

확인해보니 jasypt을 이용해 암호화가 진행되거 있었고

 

라이브러리 버전이 낮아 지원되는 알고리즘은 안전하지 못했다.. ! 

 

jasypt 버전을 올리려고보니.. SpringBoot 나 기타 다른 서비스의 버전도 올려줘야하는 부분이 있어 

 

곤란해졌다.  ( 운영중인 서비스로 리스크가 있어 여러가지 버전을 한번에 올리기가 애매한 상황.. )

 

다른 버전은 건들지 않고 

 

bouncycastle을 추가 적용해보니 더 많은 안전한 알고리즘 사용이 가능했다!

 

 

 

 

그럼 조치 시작~

 

1. lib 폴더에 bcprov-jdk15on-1.60.jar 추가 ( 첨부파일 확인 ) 

 

2.  pom.xml  Bouncycastle 추가 

<dependency>

    <groupId>org.bouncycastle</groupId>

    <artifactId>bcprov-jdk16</artifactId>

    <version>1.46</version>

    <scope>system</scope>

    <systemPath>${basedir}/lib/bcprov-jdk15on-1.60.jar</systemPath>

</dependency>

 

3. jasyptConfig.java 

* 사용가능한 알고리즘 목록 조회 

List<Object> supported = new ArrayList<>();
List<Object> unsupported = new ArrayList<>();
for (Object algorithm : AlgorithmRegistry.getAllPBEAlgorithms()) {
  try {
    StandardPBEStringEncryptor encryptor1 = new StandardPBEStringEncryptor();
    encryptor1.setPassword("somePassword");
    encryptor1.setAlgorithm(String.valueOf(algorithm));
    String str = "test";
    String encStr = encryptor1.encrypt(str);
    String decStr = encryptor1.decrypt(encStr);
    supported.add(algorithm);
  } catch (EncryptionOperationNotPossibleException e) {
  	unsupported.add(algorithm);
  }
}

for (Object s : supported) {
	System.out.println(s);
}

- 1) 암호화 

private static final String ENCRYPT_KEY = "asdasdasdasdasdasdassdwwwdd11wq";

@Test

    public void test () { 

        Security.addProvider(new BouncyCastleProvider());

        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();

        EnvironmentPBEConfig config = new EnvironmentPBEConfig();

 

        config.setPassword(ENCRYPT_KEY);

        config.setAlgorithm("PBEWITHSHA256AND256BITAES-CBC-BC");

        encryptor.setConfig(config);

 

        String url = encryptor.encrypt("jdbc:oracle:thin:@192.168.11.123:1521/ORCL");

        String username= encryptor.encrypt("testid");

        String pass = encryptor.encrypt("dbpassword");

       

        System.out.println(url);

        System.out.println(username);

        System.out.println(pass);

 

        // decrypt 테스트 

       System.out.println(encryptor.decrypt(url));

   } 

===    run as > JUnit Test 실행 

콘솔에서 암호화된 값을 확인할 수 있다.

 

 

 - 2) 적용 

@Bean("JasyptStringEncryptor")

    public StandardPBEStringEncryptor stringEncryptor() {

        Security.addProvider(new BouncyCastleProvider());

        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();

        EnvironmentPBEConfig config = new EnvironmentPBEConfig();

 

        config.setPassword(ENCRYPT_KEY);

        config.setAlgorithm("PBEWITHSHA256AND256BITAES-CBC-BC");

        encryptor.setConfig(config);

 

        return encryptor;

    }

 

application.properties  암호화된 값 입력 

spring.datasource.url=ENC(asdasdasdwwe2123123qewqwe+o46dbmkQpVu20=)

spring.datasource.username=ENC(sfsdfsr342343456efgfgdfdd==)

spring.datasource.password=ENC(gggffrrww+WbWPoAMddlLrkXFcE)

 

boot 실행 후  DB 연결이 잘 되는지 확인하기 

 

끝! 

 

관련내용) 

genie-dev.tistory.com/50?category=915648

 

jasypt를 이용한 DB 접속 정보 암호화 방법

DB 접속 정보를 암호화 하는 이유 프로젝트 내 DB 연결 값을 암호화 하지 않고 그대로 올릴 경우 서버에 직접 접근하지 않는 이상 확인하기 어렵겠지만 접속이 가능하다면 누구나 DB 정보를 확인��

genie-dev.tistory.com

새 폴더 (1).zip
3.43MB

 

현재 내가 사용중인 라이브러리에서 사용가능한 알고리즘 목록을 출력할 수 있다. 

 

버전을 올린다던지 알고리즘 변경할때 사용하면 좋을 것 같다. 

 

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentPBEConfig;
import org.jasypt.exceptions.EncryptionOperationNotPossibleException;
import org.jasypt.registry.AlgorithmRegistry;


for (Object algorithm : AlgorithmRegistry.getAllPBEAlgorithms()) {
  try { 
    StandardPBEStringEncryptor encryptor2 = new StandardPBEStringEncryptor(); 
    encryptor2.setPassword("somePassword"); 
    encryptor2.setAlgorithm(String.valueOf(algorithm)); 
    String str = "test"; 
    String encStr = encryptor2.encrypt(str); 
    String decStr = encryptor2.decrypt(encStr); 

  	System.out.println("supported :::: " +algorithm);
  } catch (EncryptionOperationNotPossibleException e) {

  	System.out.println("unsupported :::: " + algorithm);
  } 
}

 

사용가능한 알고리즘 List 보기 

import java.security.Provider;
import java.security.Security; 


for (Provider provider : Security.getProviders()) {
 	System.out.println("Provider: " + provider.getName());
 	for (Provider.Service service : provider.getServices()) {
 	cSystem.out.println("  Algorithm: " + service.getAlgorithm());
}

 

+ Recent posts