728x90

개요

GitHub의 프로젝트 레파지토리에 application.yml이나 application.properties 파일에 DB의 유저 정보와 비밀번호 또는 키값을 명시해두는 경우가 있습니다. 또한 yml이나 properties을. gitignore에 추가할 경우 aws에서 프로젝트를 실행하는 경우나 docker로 실행하는 경우 이와 같은 오류가 발생한다. "Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class” 위의 오류는 database 설정 파일을 찾지 못해서 나는 오류이다. 하지만 DB 정보를 명시해두는 경우 GitHub 특성상 오픈 소스이므로 정보가 노출되어 보안에 심각한 문제를 초래할 수 있다는 점입니다. 위와 같은 사항들을 해결하기 위해 보안에 민감한 값들을 암호화시켜 저장해야 한다.

 

암호화 방식

YML파일 암호화 방법으로는 여러 방법이 있지만 저는 Java의 Jasypt(Java Simplified Encryption) 패키지를 사용하여 설정 파일들의 암호화를 진행하겠습니다.

 

장점

Jasypt를 설정하려면 여러 코드들이 추가되지만 로컬,배포 환경의 설정 파일을 동일하게 사용할 수 있고 설정 파일이 외부 유출되어도 암호화되어있기에 비교적 안전하다는 장점이 있다.


암호화 진행 순서

1. build.gradle파일에 jasypt implementation을 작성한다.

// yml 설정 파일 암호화
implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.3'

 

2. jasyptStringEncryptor로 Bean을 등록합니다. 이 이름은 application.yml의 jasypt bean으로 등록할 때 사용합니다. private String PASSWORD는 yml 설정 파일에서 jasypt.encryptor.password으로 읽어서 가져옵니다.

import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JasyptConfig {

		@Value("${jasypt.encryptor.password}")
    private String PASSWORD;

    @Bean(name = "jasyptStringEncryptor")
    public StringEncryptor stringEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(PASSWORD); // 암호화할 때 사용하는 키
        config.setAlgorithm("PBEWithMD5AndDES"); // 암호화 알고리즘
        config.setKeyObtentionIterations("1000"); // 반복할 해싱 회수
        config.setPoolSize("1"); // 인스턴스 pool
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); // salt 생성 클래스
        config.setStringOutputType("base64"); //인코딩 방식
        encryptor.setConfig(config);
        return encryptor;
    }
}

 

3. application.yml에 암호화된 값을 적어주기 전에 미리 해당 값들의 암호화된 값을 알기위해 Test코드를 작성해서 출력한다.

import org.assertj.core.api.Assertions;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.junit.jupiter.api.Test;

class JasyptConfigTest {

    @Test
    void jasypt(){
        String url = "자신의 DB URL";
        String username = "자신의 DB USER";
        String password = "자신의 DB PASSWORD";

        String encryptUrl = jasyptEncrypt(url);
        String encryptUsername = jasyptEncrypt(username);
        String encryptPassword = jasyptEncrypt(password);

        System.out.println("encryptUrl : " + encryptUrl);
        System.out.println("encryptUsername : " + encryptUsername);
        System.out.println("encryptPassword : " + encryptPassword);

        Assertions.assertThat(url).isEqualTo(jasyptDecryt(encryptUrl));
    }

    private String jasyptEncrypt(String input) {
        String key = "암호화에 쓰일 키값";
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setAlgorithm("PBEWithMD5AndDES");
        encryptor.setPassword(key);
        return encryptor.encrypt(input);
    }

    private String jasyptDecryt(String input){
        String key = "복호화에 쓰일 키값";
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setAlgorithm("PBEWithMD5AndDES");
        encryptor.setPassword(key);
        return encryptor.decrypt(input);
    }
}

 

4. 위의 TestCode를 작성하면 암호화된 값이 출력된다.

 

5. application.yml에 암호화된 값과 jasyptStringEncryptor bean 설정

spring:
  datasource:
    url: ENC(o9FcC1LtWYlFw88yy/5Ilg==)
    username: ENC(cp/1/Ok8sPGkYEJi27Jknw==)
    password: ENC(9vlmkROOsAgMTk3rFkbiQxXFwFaQoew0)
jasypt:
  encryptor:
    bean: jasyptStringEncryptor
    password : 1234

 

jasyptStringEncryptor를 jasypt bean으로 등록하고, 각 속성값에 ENC( 암호화 값 ) 형식으로 입력해줍니다. 위와 같은 과정을 통해 application.yml 파일의 암호화를 설정해 주었습니다. 하지만, application.yml 파일 내 jasypt.encryptor.password가 노출되어있다면, 암호화는 해주었지만 암호화를 풀 수 있는 열쇠를 지어준 꼴이 된다. 이와 같은 문제를 해결하는 방법은 다음에 작성해 보겠습니다.

728x90

+ Recent posts