Hustle #8. Jasypt 암호화 라이브러리 적용
안녕하세요.
저번 포스팅까지는 AWS 인프라 설정을 세 차례나 진행했습니다.
AWS 인프라 설정에 꽤 긴 시간을 공들였는데요.
이번 포스팅에선 허슬 프로젝트에 Jasypt 암호화 라이브러리를 적용해보고자 합니다.
왜 Jasypt 암호화 라이브러리를 적용하나요?
지난 번에 스프링 부트에서 Jasypt 암호화 라이브러리를 적용해 본 포스팅을 올렸습니다.
2023.06.20 - [Back-End/Spring 자료실] - [스프링 부트] Jasypt 설정 암호화로 Github Repo 에 안전하게 올리기
팀원이 application.yml 을 .gitignore 에 포함시키고 단체방에 아래처럼 application.yml 내용을 공유했는데요.
위 포스팅에서 나온 대로 역시나, application.yml 설정이 변경 되는 대로 수시로 팀원 4명이 다 업데이트 해야 하는 불편함이 있었습니다.
암호화된 채로 깃허브 레포지토리에도 안전하게 올릴 수 있으면
더 이상 수동으로 업데이트하지 않아도 됩니다.
Jasypt 암호화 라이브러리를 사용하면 어떻게 되나요?
Jasypt 암호화 라이브러리를 사용하면 아래처럼 암호화를 시킬 수 있습니다.
spring:
jpa:
hibernate:
ddl-auto: none
datasource:
driver-class-name: ENC(4zv7k66bl0S9CkPE2DhjRaIxsA8E9l+kWvMMPExbdHg==)
url: ENC(n4BgVC45DNHZ7Dv+eIGHp6NmDrt9UOq+Eb4lRi9oP6by9eJ3NuZGKrnk1QUdrQ4J2QFWMTvqV9AuCG2y500vtLwPJngcLnbAz1JxooZAJoNCxYOyW1HwFnOY0zEqGA45hhAZxCpZEKn4IPiX8JOxYZpl13BDw/qoExcYplGW3GJVD3mhD1Yqy2B)
username: ENC(3IlDHh9Hevic4hySvk20q)
password: ENC(Z9yNmaE1Sk5DKZerehtnl+GNz3obGfbaLU=)
암호화 키는 팀 내부에서 공유하고 관리됩니다.
깃허브에 올려도 다른 사람은 암호화 키를 모르기에 원래 문자열(평문)이 무엇인지 알 수 없습니다.
Jasypt 암호화 라이브러리 적용
build.gradle 에 아래 jasypt 의존성을 추가합니다.
dependencies {
...
// jasypt
implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5'
...
}
JasyptConfig 설정 빈을 등록합니다.
package com.sporthustle.hustle.common.config;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JasyptConfig {
@Value("${jasypt.encryptor.password}")
private String key;
private static final String ALGORITHM = "PBEWithMD5AndDES";
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(key);
config.setAlgorithm(ALGORITHM);
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
암호화 키는 외부에서 주입합니다.
application.yml 에 넣으면 암호화 키가 그대로 노출되는데요.
그 대신 서버를 구동할 때 jasypt.encryptor.password 키로 주입합니다.
허슬 팀 같은 경우엔 암호화 키는 아래처럼 노션에 공유했습니다.
이제부터 빌드할 때나 Jar 파일을 실행할 때 jasypt.encryptor.password 값을 주입해야 합니다.
# 허슬 프로젝트 빌드
$ ./gradlew build -Djasypt.encryptor.password=''
# Jar 파일 실행
$ nohup java -jar hustle-v0.0.1.jar --jasypt.encryptor.password='' &
암호화된 문자열은 어떻게 얻나요?
그렇다면 암호화된 문자열은 어떻게 얻는걸까요?
허슬 서버를 구동할 때마다 암호화 된 문자열을 얻는 코드를 작성해야 할까요?
하나의 방법일 순 있지만 실제 서버 실행에 필요한 코드가 아니고 매 번 주석 처리 하기도 번거로울 것 같습니다.
다른 방법은 무엇이 있을까요?
바로 테스트 코드를 활용합니다.
package com.sporthustle.hustle.jasypt;
import static org.assertj.core.api.Assertions.assertThat;
import com.sporthustle.hustle.common.config.JasyptConfig;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.junit.jupiter.api.Test;
public class JasyptTest extends JasyptConfig {
@Test
public void 평문_암호화_결과_출력() {
String encryptKey = System.getProperty("jasypt.encryptor.password");
// 암호화할 평문 작성하기
String plainText = "";
StandardPBEStringEncryptor jasypt = new StandardPBEStringEncryptor();
jasypt.setPassword(encryptKey);
String encryptedText = jasypt.encrypt(plainText);
String decryptedText = jasypt.decrypt(encryptedText);
// 테스트 결과에서 암호문 확인 가능
System.out.println(encryptedText);
assertThat(plainText).isEqualTo(decryptedText);
}
}
테스트 코드를 작성하고 실행할 때 마다 테스트 결과에서 암호화된 문자열을 얻을 수 있게 합니다.
plainText 변수에 평문을 입력하고 테스트를 실행합니다.
테스트 결과에서 암호문을 확인합니다.
테스트 코드를 실행할 때에도 jasypt.encryptor.password 을 주입해야 합니다.
build.gradle 에서 Gradle 빌드 시 테스트 코드를 실행하는 테스트 단계에서 프로퍼티를 가져와야 합니다.
tasks.named('test') {
useJUnitPlatform()
systemProperty "jasypt.encryptor.password", System.getProperty("jasypt.encryptor.password")
}
인텔리제이 IDE 에서 실행할 때 메인 어플리케이션 클래스와 테스트 클래스에 VM Options 을 추가하여 적용합니다.
-Djasypt.encryptor.password=암호화키
마무리
이제 .gitignore 에서 다시 application.yml 파일이 추가되도록 수정합니다.
암호화 키를 노출되지 않도록 주의하기만 하면 됩니다.
더 이상 단체방에서 매 번 application.yml 파일을 수정하지 않아도
안심하면서 깃허브 레포지토리에 올려 형상 관리를 할 수 있게 했습니다.
단체방에서 공유하던 팀원도, 처음에는 왜 Jasypt 를 적용하는 지 이해를 못했었어요.
의존성 하나 추가하고 설정만 조금 건드리면 모두가 편한 걸 경험하니
Jasypt 의 편리함을 알게 되고 application.yml 이 수정할 때 마다 공유하지 않아도 된다는 점이
무척 편하다고 하셨습니다. ☺️