[Toy Project] Jasypt를 사용한 프로퍼티(application.properties) 암호화

최지나·2024년 3월 20일

스터디 관리 시스템

목록 보기
13/13
post-thumbnail
  • 토이 프로젝트가 거의 완성되어 배포하기 직전 단계에 왔다. 이에 빠진 거 없나? 하고 코드 검토를 하던 중 application.properties 파일에 DB 접속 정보나 아이디 비번과 같은 중요 정보들이 그대로 노출되어 있는 것을 발견했다
  • 이에 Jasypt 를 사용해서 프로퍼티 암호화를 진행해 보았다

Jasypt란?

  • 암복호화를 지원해주는 오픈 소스 Java 라이브러리
  • 대칭키 암호화 방식을 사용한다 (키 1개 사용)

사용 방법

  1. 의존성 추가
  • build.gradle
implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.3'
  1. 암복호화

이 부분에서 고민이 있었다. 다른 application.properties 암복호화와 관련된 글을 찾아보면

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

이런 식으로 yml에서 암복호화 시 사용할 key를 가져오는 경우가 많았다. 하지만 이렇게 되면 결국 application.properties 파일에 있는 주요 정보(DB 접속 정보 등)들을 다른 사람들도 복호화할 수 있는 것 아닌가?! 그래서 secretKey는 공개하지 않으면서, 암호화를 진행하기 위해, key를 환경변수로 등록한 뒤 가져오게 설정하였다

  • 환경 변수 등록 (윈도우)
    • 시크릿키에 특수문자를 포함하는 경우 반드시 ""로 묶어 주어야 한다
setx JASYPT_ENCRYPTOR_PASSWORD "[시크릿키]"
  • JasyptConfig.java
@Configuration
@EnableEncryptableProperties
public class JasyptConfig {

    private static final String JASYPT_PASSWORD_ENV_VAR = "JASYPT_ENCRYPTOR_PASSWORD";

    private String PASSWORD;

    public JasyptConfig() {
        this.PASSWORD = System.getenv(JASYPT_PASSWORD_ENV_VAR);
    }

    @Bean("jasyptStringEncryptor")
    public StringEncryptor stringEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(PASSWORD);
        config.setPoolSize("1");
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setStringOutputType("base64");
        config.setKeyObtentionIterations("1000");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        encryptor.setConfig(config);
        return encryptor;
    }
}
  1. 암복호화 Test
  • 제대로 암복호화가 되었는지 확인하기 위한 Test를 생성하였다.
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@DisplayName("암복호화 테스트.")
@SpringBootTest
public class JasyptConfigTest {

    private static final String JASYPT_PASSWORD_ENV_VAR = "JASYPT_ENCRYPTOR_PASSWORD";

    private String password;

    public JasyptConfigTest() {
        this.password = System.getenv(JASYPT_PASSWORD_ENV_VAR);
    }

    @Test
    void stringEncryptor() {
        String dbUrl = "dbUrl";
        String dbUsername = "dbUsername";
        String dbPassword = "dbPassword";

        System.out.println("En_dbUrl : " + jasyptEncoding(dbUrl));
        System.out.println("En_dbUsername : " + jasyptEncoding(dbUsername));
        System.out.println("En_dbPassword : " + jasyptEncoding(dbPassword));
    }

    @Test
    void stringDecryptor() {
        String dbUrl = "gQS6Big/3WlqTjFY4FGrxg=="; // dbUrl
        String dbUsername = "gMs64oreSLpvxiF2Oebv0DmS7+1vhfTQ"; // dbUsername
        String dbPassword = "lGmWk51pN3awpHLazWK68jihvfKxV8Ro"; // dbPassword

        System.out.println("DE_dbUrl : " + jasyptDecoding(dbUrl));
        System.out.println("DE_dbUsername : " + jasyptDecoding(dbUsername));
        System.out.println("DE_dbPassword : " + jasyptDecoding(dbPassword));
    }

    private String jasyptEncoding(String value) {
        return jasyptProcessor(true, value);
    }

    private String jasyptDecoding(String value) {
        return jasyptProcessor(false, value);
    }

    private String jasyptProcessor(boolean encrypt, String value) {
        StandardPBEStringEncryptor pbeEnc = new StandardPBEStringEncryptor();
        pbeEnc.setAlgorithm("PBEWithMD5AndDES");
        pbeEnc.setPassword(password);
        return encrypt ? pbeEnc.encrypt(value) : pbeEnc.decrypt(value);
    }
}

  1. application.properties 수정
  • 3.의 stringEncryptor test를 돌려 얻어진 암호화된 값들을 ENC()사이에 넣어주면 된다.
  • application.properties
spring.datasource.url=ENC(FgQS6Big/3WlqTjFY4FGrxg==)
spring.datasource.username=ENC(gMs64oreSLpvxiF2Oebv0DmS7+1vhfTQ)
spring.datasource.password=ENC(lGmWk51pN3awpHLazWK68jihvfKxV8Ro)

  • application.properties 파일의 암호화/복호화가 가능하게 함으로써 public repository에서도 안전하게,,! 프로퍼티 값들을 보관할 수 있게 설정할수 있게 되었다 😆
profile
의견 나누는 것을 좋아합니다 ლ(・ヮ・ლ)

3개의 댓글

comment-user-thumbnail
2024년 3월 20일

잘봤습니다! 질문이 하나 있어용!
이와 같이 OS 환경변수로 값을 숨긴다면 setx JASYPT_ENCRYPTOR_PASSWORD "[시크릿키]"
주인장님 PC에만 저장이 될 것 같은데, 다른 Collaborator와 함께할 때는 어떻게 진행하실 예정이신가요~?

2개의 답글