Jasypt 활용 목적
우리 솔루션은 .env 파일에 변수를 따로 정리해 두고, docker-compose.yml 파일에서 참조하여 사용하고 있다. 이 .env 파일에 적혀있는 DB 패스워드값이 평문이기 때문에 이를 암호화하고자 한다. 임의의 secretKey를 지정하여 해당 패스워드를 암호화하고, 이를 .env파일에 넣으면 된다.
jasypt 설치
라이브러리 종류
나는 폐쇄망에서 개발 중이었기 때문에, 인터넷에서 jar 파일을 다운로드하여 반입해야 한다. 그 과정에서 jasypt 라이브러리의 타입이 다양해서 처음에는 무엇을 설치해야 할지 헷갈렸다.
우선 공식 git 레포지토리를 찾아보면 두 가지가 나온다. (jaspyt 깃허브 & jasypt spring boot 깃허브) 전자는 일반 jasypt 라이브러리에 대한 페이지이며 후자는 spring boot와의 통합을 위한 라이브러리에 해당한다. 즉 나는 스프링 코드에 사용할 것이기 때문에 후자를 다운로드 하면된다.
이제 jar 파일 다운로드를 위해 maven central repository에 “jasypt spring boot”를 검색했다. 그랬더니 일반 jasypt spring boot와 jasypt spring boot starter가 있었다. Jasypt Spring Boot는 asypt를 Spring Boot 애플리케이션에서 사용할 수 있게 해주는 기본 라이브러리이며, starter는 Jasypt Spring Boot를 Spring Boot 애플리케이션에 통합하기 쉽게 만든 스타터 라이브러리이다. pring Boot의 starter는 Spring Boot 애플리케이션에서 특정 라이브러리를 더 쉽게 사용할 수 있도록 도와주는 구성요소이다.
기본 설정 변경
gradle 설정
build.gradle 파일에서 해당 라이브러리를 사용하고자 하는 모듈에 아래와 같이 implementation 을 추가하고, gradle reload를 실행한다.
subprojects {
dependencies {
implementation 'com.github.ulsebocchio:jasypt-spring-boot-starter:3.0.5'
}
}
Config 생성
@Configuration
@EnableEncrypableProperties
@ComponentScan("com.hanafn.ocr")
public class JasyptConfig {
private static final String ALGORITHM = "PBEWithMD5AndDES";
private String encryptKey = "test"; // secretKey에 해당
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor(){
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
encryptor.setPassword(encrytKey);
config.setAlgorithm(ALGORITHM);
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
각 모듈 설정 파일 수정
jasypt:
encryptor:
bean: jasyptStringEncryptor
.env 파일 수정
다음과 같이 ENC() 로 감싼 암호화 텍스트로 패스워드 변수를 수정해준다.
db_password=ENC("암호화된 텍스트")
ex: ENC(xUtTur3ookt8ibe....)
로컬 테스트
패키지 설정
물론 스프링 애플리케이션에 암복호화를 하는 코드를 작성해서 테스트해봐도 되지만, 나는 그게 귀찮았다. 그래서 spring-boot-starter 패키지 외에도 별도로 일반 jasypt 패키지를 다운받아 윈도우 cmd 창에서 테스트를 진행했다. Github 레포지토리의 README에서 :Download distributable: jasypt 1.9.3 (binaries and javadocs)” 링크를 클릭해 다운받았다.
암복호화 로컬 테스트
다운받은 파일을 압축 해제하고, cmd 상에서 [압축 해제 경로]/bin으로 이동한 뒤 아래 명령을 실행하면 된다. 암호화 시 나오는 output은 실행할 때마다 달라지는 것이 정상이다. 여기서 입력되는 “password”값이 JasyptConfig의 “encryptKey” 값과 동일해야 한다.
# 암호화 테스트
encrypt.bat input="[암호화할 텍스트]" password="test" algorithm="PBEWithMD5AndDES"
# 복호화 테스트
decrypt.bat input="[암호화결과 output]" password="test" algorithm="PBEWithMD5AndDES"
테스트
컨테이너 실행
내 경우 mariaDB 컨테이너가 우선적으로 실행된 뒤 나머지 서버(config, discovery 등)이 실행되도록 되어있다. Jasypt는 자바 코드 기반으로 동작하는데, 가장 우선적으로 올라가야 할 mariaDB는 openJDK가 설치되어 있지 않기 때문에 해당 암복호화 기능을 사용할 수는 없다.
상사에게 문의해본 결과, 해당 부분이 문제가 되는 이유는 초기 솔루션 설치 시점이 아니라 운영 도중이라고 하며, 즉 처음에 컨테이너가 올라갈 때에는 .env 파일에 패스워드 평문을 쓰는 것은 아무런 상관이 없다는 답변을 받았다. 따라서 솔루션 설치 시에는 평문을 사용하여 DB만 컨테이너 이미지를 생성하고, 나머지는 암호화된 텍스트를 넣어 실행시키면 된다.
# 평문이 저장된 .env 파일 사용
docker compose up -d mariadb_test
# 암호화된 텍스트가 저장된 .env 파일 사용
docker compose up -d --no-recreate
그래서 우선 DB 컨테이너만 명시해서 docker-compose up을 해준 뒤, 패스워드값을 변경하고 나머지 컨테이너를 생성해줬다. 이때, --no-recreate 옵션이 있어야 이전에 생성한 DB 컨테이너가 영향을 받지 않는다.
컨테이너 변수 확인
로그를 확인해보니 서버가 모두 실행되긴 했는데.. 정말 패스워드값이 서로 다르게 적용된 게 맞은걸까? 이를 확인하기 위해 docker inspect로 컨테이너에 적용된 환경변수 값을 조회해봤다. grep 시에는 “Env” 를 정확히 입력해야 한다. (대소문자를 구분하기 때문) DB 컨테이너와 일반 컨테이너 조회 결과 아래와 같이 출력되어, 정상적으로 적용되었음을 확인할 수 있었다.
docker inspect [컨테이너명] | grep "Env" -A 20
## DB 컨테이너 조회 결과 ##
"Env": {
"MYSQL_PASSWORD=[패스워드 평문]"
}
## 일반 컨테이너 조회 결과 ##
"Env": {
"db.password=ENC([암호화된 텍스트])"
}
References
'Backend > spring' 카테고리의 다른 글
Spring Cloud란?(Eureka, zuul) (0) | 2025.03.27 |
---|