[Spring] JASYPT를 사용한 프로퍼티 암호화

이멀젼씨

·

2021. 7. 27. 11:43

목적

git의 public repository와 CI/CD를 연동해 어플리케이션을 배포하는데 있어 중요한 정보가 탈취되는 것을 막기 위함

목차

  1. JASYPT란?
  2. 사용방법

1. JASYPT란?

홈페이지에 가보면 아래와 같이 적혀있다.

Jasypt is a java library which allows the developer to add basic encryption capabilities to his/her projects with minimum effort, and without the need of having deep knowledge on how cryptography works.

Jasypt는 개발자가 암호화 작동 방식에 대한 깊은 지식 없이도 최소한의 노력으로 자신의 프로젝트에 기본 암호화 기능을 추가할 수 있도록 하는 Java 라이브러리입니다.

정말 간단하게 라이브러리 추가, 암호화, key값 넘겨주기 세 가지 단계로 프로퍼티를 암호화하여 관리할 수 있다.

2. 사용방법

1. 라이브러리 추가

implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.3'

gradle의 의존성에 추가해준다.

2. 기본설정

https://github.com/ulisesbocchio/jasypt-spring-boot#use-you-own-custom-encryptor
나만의 key를 사용해서 Bean을 등록하는 기본 설정이다.

@Configuration
public class JasyptConfig {

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

    @Bean("jasyptStringEncryptor")
    public StringEncryptor stringEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(password);
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        return encryptor;
    }
}

password는 프로퍼티 내부에 있으면 안되므로, 외부에서 주입받아 설정해주는 방식으로 하였다.

3. 프로퍼티 암호화

https://www.devglan.com/online-tools/jasypt-online-encryption-decryption

위의 사이트에 방문하여 암호화 할 수 있다.

 

 

암호화 시, 암호화 하고자 하는 값을 넣고 'Two Way Encryption(With Secret Text)'를 선택 후 Secret Key를 넣은 뒤 Encrypt버튼을 눌러주면 암호화 된 결과가 나온다.

반대로 암호화 된 값을 옆에 Decrypt하는 곳에 넣고 똑같이 Secret Key를 넣으면 원래의 값이 나오게 된다.

spring:
  datasource:
    url: testurl
    username: sa
    password: sa
    driver-class-name: h2
spring:
  datasource:
    url: ENC(xNaJx2/9+OHzb5d7XKfdNQ==)
    username: ENC(SXTfVV3MGkzW070T/qgJxQ==)
    password: ENC(SXTfVV3MGkzW070T/qgJxQ==)
    driver-class-name: ENC(jfl2bJ1aewTZ9elDI/7nSQ==)

원래의 같이 평문이였다면 암호화 후엔 ENC 라는 문자를 붙여주고, 그 안의 괄호에 암호화 된 값을 넣어주면 된다.

4. Password 전달

제일 중요한 부분이다.

Password값을 application.yml에 넣는다면 누구나 복호화할 수 있게 되므로 의미가 없어진다.

그렇기 때문에 직접 외부에서 전달해주어야 한다.

  • java -jar 명령어로 어플리케이션 실행 시 전달
--jasypt.encryptor.password=testkey

java명령어를 사용해 어플리케이션을 실행하는 경우엔 맨 마지막에 -- 를 사용하여 패스워드를 전달해준다.

'--' 앞의 jasypt.encryptor.password 는 '2. 기본설정' 에서 @Value 안에 넣어준 값과 동일해야 한다.

  • gradle에서 build 시 test의 프로퍼티로 전달

gradle에서 build를 진행하게되면 기본적으로 test도 같이 실행된다.

이때 암호화를 이용하여 같이 테스트를 하려 한다면 build 실행 시 Password를 함께 전달해주어야 한다.

-Pjasypt.encryptor.password=testkey

우선 build명령어 실행 시 -P를 사용하여 gradle의 환경변수로 넘겨준다.

test {
    useJUnitPlatform()
    systemProperty 'jasypt.encryptor.password', findProperty("jasypt.encryptor.password")
}

systemProperty는 키, 값 쌍을 인자로 테스트 수행 JVM의 시스템 프라퍼티 지정하는 메소드이다.

findProperty를 통해 '-P' 이하로 입력된 속성을 찾아서 JVM의 시스템 프로퍼티로 지정해준다.

위와 같이 사용하면 public repository에서도 application.yml을 안전하게 보관할 수 있다.