-
[Spring Boot] Jasypt를 통한 암복호화 - application.properties에서 db 암호화개발기록 2022. 9. 21. 14:00반응형728x90
개요
현재 프로젝트는 gradle이며, 멀티모듈을 시도하고 있다.
이에 맞는 코드가 구글링했을 때, 테스트코드와 멀티모듈 시 어떻게 하는 지에 대해서 딱히 안 나와서 참고하는 블로그 글을 토대로 프로젝트에 맞게 바꾸고 기록한다.
암복호화에 사용될 알고리즘으로 PBEWithMD5AndDES을 사용했다.
개발 순서 및 코드
1. build.gradle
build.gradle에 필요한 dependency들을 추가한다.
dependencies { // 설정파일 암호화 dependency // https://mavenlibs.com/maven/dependency/com.github.ulisesbocchio/jasypt-spring-boot api 'com.github.ulisesbocchio:jasypt-spring-boot:3.0.4' // 암호 알고리즘 dependency // https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15to18 api 'org.bouncycastle:bcprov-jdk15to18:1.71' }
2. JasyptConfig.java
PBEWithMD5AndDES 알고리즘을 사용하여 이번 게시물에서 가장 핵심인 JasyptConfig.java를 만든다.
password의 경우 하드코딩보다는 application.properties에서 프로퍼티로 선언하고 가져다 쓰는 방식을 쓰기로 한다.
2-1. application.properties
# Jasypt Config jasypt.encryptor.password=test jasypt.encryptor.property.prefix=ENC( jasypt.encryptor.property.suffix=)
jasyptConfig.java에서 해당 프로퍼티를 변수로 선언해서 사용한다.
2-2. JasyptConfig.java
package com.??.config; import com.ulisesbocchio.jasyptspringboot.configuration.EnableEncryptablePropertiesConfiguration; 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; import org.springframework.context.annotation.Import; @Configuration @Import(EnableEncryptablePropertiesConfiguration.class) public class JasyptConfig { @Value("${jasypt.encryptor.password}") private String jasyptPassword; @Bean("jasyptEncryptor") public StringEncryptor stringEncryptor() { PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor(); SimpleStringPBEConfig config = new SimpleStringPBEConfig(); config.setPassword(jasyptPassword); // 암호화 키 config.setAlgorithm("PBEWithMD5AndDES"); // 알고리즘 config.setKeyObtentionIterations("1000"); config.setPoolSize("1"); config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); config.setStringOutputType("base64"); encryptor.setConfig(config); return encryptor; } }
위 코드에서
@Import(EnableEncryptablePropertiesConfiguration.class)
를 안 써주면
import com.ulisesbocchio.jasyptspringboot.configuration.EnableEncryptablePropertiesConfiguration;
import 구문이 적용 안 되면서 에러를 발생시킨다.
이유에 대해서는 더 공부해봐야겠다,,
이 부분을 구글링해서 해결하는데 애먹었던 기억이있다,,
하지만 이미 다 구현한 후 게시물을 작성하며 정리하고 있기 때문에 참고한 게시물 출처는 어디인 지 모르겠다,,
3. Test코드 작성
Assertions.assertThat 코드를 사용해서 암복호화가 제대로 작동하는 지 확인한다.
※ 콘솔에 찍어보고 싶으면 log.info()를 사용한다. 이 경우에 @Slf4j를 사용하기 위해서 필요한 의존성을 추가해줘야한다.
package com.??.config; import org.assertj.core.api.Assertions; import org.jasypt.encryption.StringEncryptor; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(classes = JasyptConfig.class) public class JasyptConfigTests { final BeanFactory beanFactory = new AnnotationConfigApplicationContext(JasyptConfig.class); final StringEncryptor stringEncryptor = beanFactory.getBean("jasyptEncryptor", StringEncryptor.class); @Test @DisplayName("암복호화 테스트") void encryptorTest() { String keyword = "plain text"; String enc = stringEncryptor.encrypt(keyword); String des = stringEncryptor.decrypt(enc); assertThat(keyword).isEqualTo(des); // 틀릴 경우 에러 // Assertions.assertThat(keyword).isEqualTo(enc); // 에러 // Assertions.assertThat(enc).isEqualTo(des); // 에러 } }
Test코드를 작성한다고 java의 reflection과 asserThat을 구글링하면서 찾아봤던 기억이 난다.
이 부분에 대해서는 날잡고 따로 정리를 한 번 해야겠다.
cf) asserThat을 썼을 때 틀릴 경우 에러가 발생한다.
4. 상속
core가 되는 모듈에서 암복화를 구현했다. 현재 프로젝트는 멀티모듈을 시도하고 있기 때문에 다른 모듈에서 사용할 때에는 해당 클래스(JasyptConfig.java)를 상속받아 사용한다.
package com.????.config; import com.kvaram.??.JasyptConfig; import org.springframework.context.annotation.Configuration; @Configuration public class ChildJasyptConfig extends JasyptConfig { }
※ core 모듈의 의존성들을 그대로 사용할 경우, 해당 모듈의 build.gradle
만약 core 모듈 명이 jeongwoo-core라면 implementation project(':jeongwoo-core')로 적어주면 된다.
ex)
dependencies { implementation project(':core가 되는 모듈명') }
5. application.properties 적용
jasypt.encryptor.bean=jasyptEncryptor 을 명시하여 jasyptEncryptor의 이름을 가진 Bean이 복호화할 것임을 알려준다.
# Jasypt Config jasypt.encryptor.bean=jasyptEncryptor jasypt.encryptor.password=test jasypt.encryptor.property.prefix=ENC( jasypt.encryptor.property.suffix=) # DB Connection Information spring.datasource.driver-class-name=org.mariadb.jdbc.Driver spring.datasource.url=ENC("암호화된 문자열") spring.datasource.username=ENC("암호화된 문자열") spring.datasource.password=ENC("암호화된 문자열")
※ cf) Test 코드에서 암복호화가 필요한 문자열을 암호화한다.
암호화된 문자열을 ENC()안에 적고 사용한다(단, 이때 ""로 묶어줄 필요는 없다.).
ex)
spring.datasource.username=ENC(testEncString)
※ 가장 중요한 것은 password이다. 도중에 password를 바꾼다면 기존에 있던 암호화된 문자열들을 사용할 수 없다.
따라서 도중에 password를 바꾸고싶다면 바꾼 password로 다시 암호화한 후 반환된 문자열을 사용해야한다.
참고: https://dejavuhyo.github.io/posts/encrypt-configuration-file-in-springboot/
728x90'개발기록' 카테고리의 다른 글
[Spring Boot] Mybatis 설정(In application.properties) (0) 2022.09.27 [Error, Spring Boot + JPA] repository 위치 변경 시 에러 (0) 2022.09.22 [Spring Boot] Gradle 프로젝트에 외부 라이브러리(*.jar) 추가하는 방법 (0) 2022.09.21 [Spring Boot] 스케쥴러를 이용한 스케쥴링(Scheduler) (0) 2022.09.19 [Spring Boot] request, response 로그 남기기2 - logback(파일로 로그 남기기) (1) 2022.09.14