[Spring]암호화 및 복호화 해보기 - Jasypt

Inung_92·2023년 10월 16일
1

Spring

목록 보기
14/15
post-thumbnail

포스팅 목적

📖DB 연결 정보 등 애플리케이션을 개발하면서 다루는 민감 정보들에 대한 암호화하여 혹시라도 모를 정보 노출에 대비해보자.

소개

개념

📖“Jasypt is a java library which allows the developer to add basic encryption capabilities to his/her projects with minimum effort, and without the need of having deep knowledge on how cryptography works.”

Jasypt는 최소한의 노력과 깊은 암호화 지식 없이 개발 과정에서 손 쉽게 암호화 기능을 사용하도록 도움을 주는 Java의 라이브러리이다.

주요 특징은 다음과 같다.

  • 단방향 및 양방향 암호화를 위한 높은 보안의 표준 기반 암호화 기술
  • Hibernate와 투명한 통합이 가능
  • Spring 기반 애플리케이션에 적합하며 Spring Security와도 통합 가능
  • 멀티 프로세서 및 코어 시스템의 고성능 암호화 가능
  • 완전한 thread-safe 지

사용 목적

📖SpringBoot를 통한 웹 애플리케이션 개발 시 DB 연동 정보와 같은 민감 정보가 외부로 노출되는 것을 차단하기 위하여 사용한다.

다음과 같이 등록 할 DB 정보가 있다고 가정하자.

spring:
		datasource:
			driver-class-name: org.postgresql.Driver
			url: jdbc:---
			username: user1234
			password: pass1234

위와 같이 properties파일의 DB URL 및 password는 노출되면 DB에 접근이 가능하도록 힌트를 주는 민감 정보들이다. 이러한 정보들은 애초에 git 등의 원격 저장소에 commit을 하지 않는 것이 올바르겠지만 혹시라도 실수로 commit을 하더라도 이런 정보들에 대한 노출을 차단하기 위해서 암호화를 통해 접속에 대한 시도가 불가능 하도록 Jasypt를 사용하는 것이다.

사용

dependency 설정

dependencies {
	implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5'
}

Bean 정의

@Configuration
@EnableEncryptableProperties
public class JasyptConfigAES {

    @Bean("jasyptEncryptorAES")
    public StringEncryptor stringEncryptor(){
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        String encryptKey = "testKey";

        config.setPassword(encryptKey); // 암호화 키
        config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256"); // 적용 알고리즘
        config.setKeyObtentionIterations("1000"); // 해싱 반복 횟수
        config.setPoolSize("1"); // 인스턴스 Pool 개수
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); // salt 생성
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        config.setStringOutputType("base64"); // 인코딩 방식
        encryptor.setConfig(config);

        return encryptor;
    }
}

주요 클래스의 설명은 다음을 참고하자.

  • PooledPBEStringEncryptor : 텍스트 기반 데이터 암/복호화 시 사용된다. 특히 암호화된 문자열을 풀링하여 효율적으로 암/복호화 수행하는데 이것은 작업에 사용되는 비용을 줄이고 재사용성을 높이기 위한 목적으로 사용된다.
  • SimpleStringPBEConfig : 문자열 기반의 PBE(Password-Based Encryption) 설정을 담당한다. 비밀번호를 기반으로 하는 암호화 기술로 암호화 키를 생성하여 데이터를 암/복호화한다. 즉 PBE 알고리즘을 설정하고 관리하기 위해 사용된다.

위 코드에서 중요한 부분은 config.setPassword() 메소드이다. 여기서의 password는 암/복호화를 수행시키기 위해 필요한 key값을 넣는 것이다. 즉 외부로 노출 될 경우 암/복호화의 key값이 노출되기 때문에 누구든지 암호화된 정보를 복호화 할 수 있게 된다. 이 부분에 대한 자세한 설정은 뒤에서 알아보자.

Bean 추가

jasypt:
  encryptor:
    bean: jasyptEncryptorAES

Bean을 정의할 때 @Bean 어노테이션에 작성한 이름과 동일하게 설정을 해준다.

암호화

암/복호화를 하기 위해서는 애플리케이션 실행과 별도로 Test를 통해 정보를 입력해주어야한다. 다음 코드는 Junit을 통한 암호화 코드이다.

@EnableConfigurationProperties
class JasyptConfigAESTest {

    @Test
    @DisplayName("DB 정보 암호화 테스트")
    void stringEncryptor() {
        String url = "test";
        String username = "test";
        String password = "test";

        System.out.println(jasyptEncoding(url));
        System.out.println(jasyptEncoding(username));
        System.out.println(jasyptEncoding(password));
    }

    public String jasyptEncoding(String value) {
        StandardPBEStringEncryptor stringEncryptor = new StandardPBEStringEncryptor();
        String key = "testKey";
        System.out.println(key);
        stringEncryptor.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        stringEncryptor.setPassword(key);
        stringEncryptor.setIvGenerator(new RandomIvGenerator());

        return stringEncryptor.encrypt(value);
    }
}

이렇게 코드를 작성하고 stringEncryptor() 테스트 메소드를 실행하면 다음과 같은 결과가 나온다.

암호화된 값을 얻으면 해당 정보를 통해 DB 연결 정보를 설정하면된다.

DB 연결

DB의 연결은 기존 정보에서 ENC() 를 붙여서 암호화된 값을 입력해주면 된다.

spring:
		datasource:
			driver-class-name: org.postgresql.Driver
			url: ENC(RCsu829rvSjZqbS8YoYdkTXfOKFwh+rfzDBKBJZziGalValhF4IU4ckHGDnz4EDA)
			username: ENC(fIArV7xNVtSLF8RZIcpjq/X9LmlN+IR0tPWh64DTb+UQFy4s9l7cRMMRUMDrNWW8)
			password: ENC(SFrWA6MMJsdcRA9YkYRX5aZ1rWBGJbhxywvsn1gqhb9nEchTe/voIE0pV/ci4c2M)

이러한 형태로 연결을 해주면 암호화된 DB 연결 정보 설정이 마무리 된다.

주의사항

위에서 암호화를 수행할 때 key값을 설정해주는 것이 중요하다고 언급했다. 기껏 암호화를 통해 노출을 방지했는데 암호화를 수행할 때 사용한 key값이 노출된다면 모든게 무용지물이다. 그렇기 때문에 암호화에 필요한 key값은 외부 또는 환경변수로 받아오는 것이 조금 더 안전하다고 볼 수 있다.

나는 Intellij를 사용하기 때문에 해당 IDE를 기준으로 설명하겠다. 방법은 다음과 같다.

환경변수 설정

  1. Edit Configuration 클릭

  1. Environment variables에 key값 등

  1. 아래 코드와 같이 키값 호출
...생략
String key = System.getenv("encryptorKey");
stringEncryptor.setPassword(key);

...

위 설정을 통해 해당하는 key값을 환경변수로 등록하여 사용할 수 있다.


마무리

얼마전까지만해도 그냥 properties 파일을 제외시키면 되겠지라는 생각으로 DB 접속 정보 등 민감정보들을 방치아닌 방치를 해두었다. 그러다 문득 암호화를 통해 연결을하면 노출이 되더라도 조금이라도 더 대처할 시간을 마련할 수 있지 않을까? 하는 바램에 알아보다가 Jasypt 라이브러리를 사용해 본 것이다.

사용하기도 생각보다 간편했고, 깊게 들어가지 않아도 내가 원하는 아웃풋을 얻을 수 있어서 다행이었던 경험인 것 같다. 이렇게 작은 부분들을 조금씩 개선해 나가면서 포스팅으로 정리하면 나중에도 당연히 써먹게 되는 부분들이 있는 것 같다는 생각이 든다.

그럼 이만.👊🏽

profile
서핑하는 개발자🏄🏽

0개의 댓글