데이터베이스를 팀원들과 공유하는 과정에서 aws RDS를 사용하게 되었다
RDS를 사용하기 위해서는 엔드포인트, 사용자이름, 사용자 비밀번호가 필요하다
spring boot 프로젝트를 생성해 application.properties에 위의 정보들을 넣어주어야 하는데
github에 공유시 정보들( 엔드포인트, 사용자이름, 사용자 비밀번호)이 유출되는 문제가 있었다.
이를 암호화하고 팀원들만 복호화할 수 있도록 하기 위해 Jasypt를 사용하게 되었다.
의존성 추가
먼저 build.gradle에 아래의 코드를 추가하자
main과 test 두 군데에 추가하였다
dependencies {
// jasypt 라이브러리 추가
implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-web-services'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools
implementation 'org.springframework.boot:spring-boot-devtools:3.3.4'
// https://mvnrepository.com/artifact/org.projectlombok/lombok
annotationProcessor 'org.projectlombok:lombok:1.18.34'
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:3.3.4'
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.3.4'
// https://mvnrepository.com/artifact/nz.net.ultraq.thymeleaf/thymeleaf-layout-dialect
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.3.0'
}
tasks.named('test') {
useJUnitPlatform()
// jasypt 라이브러리 추가
systemProperty 'jasypt.encryptor.password', findProperty("jasypt.encryptor.password")
}
Test코드 작성해서 암호화하기
아래의 코드를 작성한 후, RDS 엔드포인트, 사용자 이름, 비밀번호를 입력하면, config.setPassword(" Jasypt 암호화 및 복호화 과정에서 사용되는 비밀번호 ")를 통해 " Jasypt 암호화 및 복호화 과정에서 사용되는 비밀번호 "라는 비밀번호가 암호화 과정의 핵심으로 작용하여 해당 정보들이 안전하게 암호화된 형태로 변환된다. 즉, " Jasypt 암호화 및 복호화 과정에서 사용되는 비밀번호 "는 RDS 연결 정보를 보호하기 위한 암호화 키 역할을 하며, 이를 통해 데이터의 기밀성과 무결성을 효과적으로 보장할 수 있다.
package carrotmoa.carrotmoa.config;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.junit.jupiter.api.Test;
public class JasyptConfigTest {
@Test
public void jasypt_test() {
// 테스트할 값들 (RDS)
String endpoint = "엔드포인트";
String username = "사용자 이름";
String password = "비밀번호";
// Jasypt 설정
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("Jasypt 암호화 및 복호화 과정에서 사용되는 비밀번호");
// 암호화 알고리즘 및 설정
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);
// 엔드포인트 암호화
System.out.println("endpoint : " + endpoint);
String encryptEndpoint = encryptor.encrypt(endpoint);
System.out.println("encryptEndpoint : " + encryptEndpoint);
// 사용자 이름 암호화
System.out.println("username: " + username);
String encryptUsername = encryptor.encrypt(username);
System.out.println("encryptUsername : " + encryptUsername);
// 비밀번호 암호화
System.out.println("password: " + password);
String encryptPassword = encryptor.encrypt(password);
System.out.println("encryptPassword : " + encryptPassword);
// 복호화
String decrpytEndpoint = encryptor.decrypt(encryptEndpoint);
String decryptUsername = encryptor.decrypt(encryptUsername);
String decryptPassword = encryptor.decrypt(encryptPassword);
// 복호화 결과 출력
System.out.println("decryptEndpoint: " + decrpytEndpoint);
System.out.println("decryptUsername : " + decryptUsername);
System.out.println("decryptPassword : " + decryptPassword);
// 원래 텍스트와 복호화된 텍스트 비교
System.out.println(endpoint.equals(decrpytEndpoint));
System.out.println(username.equals(decryptUsername));
System.out.println(password.equals(decryptPassword));
}
}
결과
endpoint : [엔드포인트]
encryptEndpoint : I+N8+e7Cg0eYK1nZKHF5wd9DfzVa5SU5zznULkoucF+N+xpkpyUF6jvuQVX1fA6KLuvhXJkwSfRpu99c2HSr9wWajAhLWmZEMLY4sM7UD3jAyHB0MKvU4A==
username: [사용자 이름]
encryptUsername : HhIu6VAAHCSrN0hlhQp84A==
password: [비밀번호]
encryptPassword : 3tOsNE8awzmVf7dRzaFKDQZFYB76AkqMym/QFub8Hv0=
decryptEndpoint: [엔드포인트]
decryptUsername : [사용자 이름]
decryptPassword : [비밀번호]
true
true
true
원래 텍스트와 복호화된 텍스트를 비교한 결과가 모두 true로 나온 걸로 보아 암호화가 잘 이루어졌다.
출력 결과에서 encryptEndpoint, encryptUsername, encryptPassword는 각각 엔드포인트, 사용자 이름, 비밀번호가 암호화된 결과이다.
Configuration 추가
package carrotmoa.carrotmoa.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}") // VM option으로 설정된 Jasypt 암호화 비밀번호
private String encryptKey;
// 암호화기 Bean 설정
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(encryptKey);
config.setAlgorithm("PBEWithMD5AndDES");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
encryptor.setConfig(config);
return encryptor;
}
}
application.properties에 추가
JasyptConfigTest에서 출력된 암호화 정보들을 application.properites에 ENC(...) 형태로 넣어주자. ENC는 Jasypt 라이브러리에게 해당 문자열이 암호화된 데이터임을 알려준다. Jasypt는 이 값을 해독하여 실제 데이터베이스 연결 정보를 사용하게 되며, 이를 통해 애플리케이션이 데이터베이스에 안전하게 접근할 수 있도록 도와준다.
# 데이터베이스 설정(jasypt로 암호화된)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=ENC(I+N8+e7Cg0eYK1nZKHF5wd9DfzVa5SU5zznULkoucF+N+xpkpyUF6jvuQVX1fA6KLuvhXJkwSfRpu99c2HSr9wWajAhLWmZEMLY4sM7UD3jAyHB0MKvU4A==)
spring.datasource.username=ENC(HhIu6VAAHCSrN0hlhQp84A==)
spring.datasource.password=ENC(3tOsNE8awzmVf7dRzaFKDQZFYB76AkqMym/QFub8Hv0=)
VM Option추가
intellij에서 Edit Configurations 클릭
Modify options 클릭
add VM options 클릭
JasyptConfigTest에서 config.setPassword의 매개변수로 넣은 값을 입력하자
이는 Jasypt 암호화 및 복호화 과정에서 사용되는 비밀번호이다
-Djasypt.encryptor.password=[Jasypt 암호화 및 복호화 과정에서 사용되는 비밀번호]
ok를 누르면 정상적으로 실행된다
'[carrot-moa] 파이널 프로젝트' 카테고리의 다른 글
[AWS S3 / Spring boot] S3로 이미지 등록 및 이미지 삭제 (1) | 2024.10.30 |
---|---|
[Spring/Spring Boot] @ModelAttribute과 Model (0) | 2024.10.03 |