[Spring Boot] Jasypt를 이용한 암호화
개발환경
- Eclipse IDE 2022-06
- Spring Boot 3.0.0
- Gradle 7.0
- Lombok
- PostgreSQL
- jasypt-spring-boot:3.0.4
Jasypt는 개발자가 암호화 작동 방식에 대한 깊은 지식이 없어도 최소한의 노력으로 프로젝트에 기본 암호화 기능을 추가할 수 있는 자바 라이브러리이다. 프로젝트를 구동하려면 중요 정보(DB 접속정보 등)를 설정하게 되는데 소스코드를 GitHub으로 관리한다던가 서버에 소스코드를 배포하면서 의도하지 않은 중요정보를 외부에 노출하는 상황이 발생하게 된다. Jasypt를 이용하여 중요정보를 암호화하여 소스코드를 관리해보자.
- Package Explorer
- build.gradle
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '3.0.0'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example.jasypt'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.postgresql:postgresql'
implementation 'com.github.ulisesbocchio:jasypt-spring-boot:3.0.4'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
- JasyptConfiguration.java
package com.example.jasypt;
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 com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
@Configuration
@EnableEncryptableProperties
public class JasyptConfiguration {
private static final String PASSWORD = "DB_DECRYPT_KEY";
private static final String ALGORITHM = "PBEWithMD5AndDES";
private static final String KEY_OBJECTION_ITERATIONS = "1000";
private static final String POOL_SIZE = "1";
private static final String PROVIDER_NAME = "SunJCE";
private static final String SALT_GENERATOR_CLASS_NAME = "org.jasypt.salt.RandomSaltGenerator";
private static final String STRING_OUTPUT_TYPE = "base64";
@Bean("jasyptStringEncryptor")
StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(System.getenv(PASSWORD));
config.setAlgorithm(ALGORITHM);
config.setKeyObtentionIterations(KEY_OBJECTION_ITERATIONS);
config.setPoolSize(POOL_SIZE);
config.setProviderName(PROVIDER_NAME);
config.setSaltGeneratorClassName(SALT_GENERATOR_CLASS_NAME);
config.setStringOutputType(STRING_OUTPUT_TYPE);
encryptor.setConfig(config);
return encryptor;
}
}
Password : 암호화할 비밀번호 지정한다. 비밀번호 노출을 막기 위해 system.getenv 환경설정에서 정보를 가져온다.
Algorithm : 암호화 알고리즘
KeyObtentionIterations : 암호화 반복 해시 횟수, 클수록 암호화 시간은 오래 걸리지만 보안 강도는 올라간다.
PoolSize : 서버의 프로세서/코어 수를 권장한다.
StringOutputType : 암호화 값을 어떤 형태로 값을 받을지 설정한다.(base64 / hexadecimal 중 선택)
- JasyptTest.java
package com.example.jasypt.test;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
public class JasyptTest {
public static void main(String[] args) {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("jiurinie");
System.out.println("url : " + encryptor.encrypt("jdbc:postgresql://xxx.xxx.xxx:5432/playground"));
System.out.println("username : " + encryptor.encrypt("playground"));
System.out.println("password : " + encryptor.encrypt("playground"));
System.out.println("");
System.out.println("url : " + encryptor.decrypt("8y4UBRJuzMv4uSx/YIvXIP+Tdp+HGDMgyZWXQxsuLZUu+Ivc+vmEnLn2rERTcqm8r5QcyhJMxvs="));
System.out.println("username : " + encryptor.decrypt("Bc8mL9zZyOJ9Q47EHaiY0Px9mpYn0xOj"));
System.out.println("password : " + encryptor.decrypt("NfAqAfurxNw7E2dOn2g7pMCLYm0+zXmS"));
}
}
암/복호화 테스트 파일이다. 테스트 파일로서 서버 배포와는 별개로 테스트 하여야 한다. 암호화 된 값을 application.properties의 ENC() 사이에 넣으며, password로 지정한 'jiurinie' 값은 따로 환경설정으로 지정해주어 관리할 예정이다.
- application.properties
## database
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=ENC(hmZ4uvZDGB/5sa8KdFR+439G+pgJCINqe+yyi0r3D5+vP8xDTNhdAyKu+AWRiRUgdhAqFWrszAc=)
spring.datasource.username=ENC(5NmnTE0yCS0H+68hGLDHc+W1NKsZ65Ul)
spring.datasource.password=ENC(VcIq3q5yCOXcw0p7ROgi9Xv950sJVzry)
서버가 빌드될 때 복호화 하기 위해 'ENC()' 사이에 암호화 된 값을 넣는다.
- 복호화 비밀번호 설정
메뉴바 - Run - Run Configurations를 선택한다. Spring Boot의 내장톰캣을 사용한다면 Spring Boot App의 해당 프로젝트를 찾아 환경변수를 설정해준다. 이렇게 설정하면 서버가 올라가면서 DB_DECRYPT_KEY 값을 이용하여 복호화할 것이다.
메뉴바 - Run - Run Configurations를 선택한다. 외부톰캣을 사용한다면 Apache Tomcat의 해당 프로젝트를 찾아 환경변수를 설정해준다. 이렇게 설정하면 서버가 올라가면서 DB_DECRYPT_KEY 값을 이용하여 복호화할 것이다.
$ cd %TOMCAT_HOME%/bin
$ vi setenv.sh
export DB_DECRYPT_KEY="jiurinie"
리눅스 외부 톰캣 사용 시 setenv.sh 파일을 이용하여 서버가 올라갈 때 환경변수 값을 설정한다.
아래 링크에서 자세한 jasypt의 설정 정보를 확인할 수 있다
http://www.jasypt.org
'Programming > Spring Boot' 카테고리의 다른 글
[Spring Boot] No matching variant of org.springframework.boot:spring-boot-gradle-plugin:3.X.X was found. (0) | 2023.03.09 |
---|---|
[Spring Boot] Gradle을 이용한 Profile(개발/운영) 구분 설정 (0) | 2022.12.02 |
[Spring Boot] PostgreSQL 연결을 위한 JPA 설정 (0) | 2022.07.28 |
Spring Boot 기본 설정 Port, ContextPath, Session Timeout (0) | 2022.07.22 |
Spring Boot 웹 프로젝트 생성 (0) | 2022.07.08 |
댓글