Jasypt

sixhustle·2020년 12월 10일
0

Spring

목록 보기
10/10

JASYPT(Java Simplified Encryption)

  • 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 Library입니다.

언제, 왜 써야하는가?

  • Spring Boot Framework로 Database를 연동한다고 가정하겠습니다.
  • Database연동을 위해서는 아래와 같이 application.yml파일에 property설정을 해줘야 합니다.
spring:
  datasource:
    url: jdbc:mysql://localhost:13307/database?...
    username: username
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
  • application.yml파일도 gitlab/github에 push를 원하지만, password가 신경 쓰입니다.
  • 이와 같이 property encryption이 필요할 때, Jaspyt를 사용할 수 있습니다.

어떻게 적용하는가?

compile group: 'com.github.ulisesbocchio', name: 'jasypt-spring-boot-starter', version: '3.0.2'
  • Java configuartion code 추가
    • Jasypt Bean 설정을 해줍니다.
    • Encrypt시 사용되는 password, algorithmn을 설정합니다.
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 encryptKey;

    @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.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        return encryptor;
    }
}
  • application.yml jasypt 설정 추가
    • Java code의 @Bean("여기값") 과 동일하게 설정해줍니다. 위의 코드에서는 jasyptStringEncryptor 입니다.
    • Bean에 이름을 명시하지 않으면, method이름이 Bean으로 설정됩니다.
jasypt:
  encryptor:
    bean: jasyptStringEncryptor
  • Jasypt Encrypt/Decrypt Test Code 작성
    • Test Code를 작성함으로써 Enc/Dec 기능을 보장받습니다.
    • Test Code의 결과값을 application.yml파일에 적용할 것입니다.
    • encryptedText의 값은 실행할 때마다 변경됩니다.
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class AbstractServiceTest extends AbstractTest {

    @Test
    public void jasypt_encrypt_decrypt_test() {
        String plainText = "plainText";

        StandardPBEStringEncryptor jasypt = new StandardPBEStringEncryptor();
        jasypt.setPassword("password");
        jasypt.setAlgorithm("PBEWithMD5AndDES");

        String encryptedText = jasypt.encrypt(plainText);
        String decryptedText = jasypt.decrypt(encryptedText);

        assertThat(plainText).isEqualTo(decryptedText);
    }
}
  • application.yml encryption 적용
    • ENC(encryptedText) 와 같이 ENC()로 encryptedText 결과 값을 감싸줘야 합니다.
    • 언제, 왜 써야하는가? 문단의 application.yml파일에 jasypt를 적용한 값입니다.
spring:
  datasource:
    url: jdbc:mysql://localhost:13307/database?...
    username: username
    password: ENC(CcRXKgayOFJg+aAM/ihG/uyEHAb9WHaX)
    driver-class-name: com.mysql.cj.jdbc.Driver

jasypt:
  encryptor:
    bean: jasyptStringEncryptor

Jasypt의 Password는 어떻게 설정하는가?

  • Jaspyt설정에 사용되는 password도 노출되지 않게 설정이 필요합니다.
  • VM Options 사용
-Djasypt.encryptor.password=password
  • ApplicationContextInitializer
    • Spring Boot 실행시 가장 먼저 실행 해야할 기능이 있을 때 사용합니다.
    • AWS Parameter Store에서 Jasypt password를 가져와 Application에 적용하는 예제입니다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class ServiceApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(ServiceApplication.class)
                .initializers(new ServiceInitializer())
                .run(args);
    }
}
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;

public class ServiceInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        String password = getPasswordFromAWSParameterStore();
        setJasyptPassword(password);
    }

    private String getPasswordFromAWSParameterStore() {
        //  Get password from AWS        
        return "password";
    }

    private void setJasyptPassword(String password) {
        System.setProperty("jasypt.encryptor.password", password);
    }
}

질문 리스트

  • Jasypt decrytion은 언제 수행되는가?
    • Jasypt이 properties를 암호화 하고 사용하는 방식
      • Tomcat에서 Spring 프로젝트가 올라가면서 context 가 생성된다
      • 그 타이밍에 context에 있는 jasypt 객체들이 암호를 풀어준다.
      • 암호를 풀려면 “키” 가 있어야 한다.
      • 근데 결국 “키” 가 프로젝트 내부에 있으면 보안 없는거나 마찬가지 아닌가?
      • 그래서 그 “키”는 프로젝트 내부가 아니라 구동 서버의 환경변수로 존재한다. 고로 안전하다.

Reference

0개의 댓글