본문 바로가기
Programming/Spring Boot

[Spring Boot] Jasypt를 이용한 암호화

by 주리니e 2022. 11. 30.
728x90

[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

 

728x90

댓글