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() {
return "password";
}
private void setJasyptPassword(String password) {
System.setProperty("jasypt.encryptor.password", password);
}
}
질문 리스트
- Jasypt decrytion은 언제 수행되는가?
- Jasypt이 properties를 암호화 하고 사용하는 방식
- Tomcat에서 Spring 프로젝트가 올라가면서 context 가 생성된다
- 그 타이밍에 context에 있는 jasypt 객체들이 암호를 풀어준다.
- 암호를 풀려면 “키” 가 있어야 한다.
- 근데 결국 “키” 가 프로젝트 내부에 있으면 보안 없는거나 마찬가지 아닌가?
- 그래서 그 “키”는 프로젝트 내부가 아니라 구동 서버의 환경변수로 존재한다. 고로 안전하다.
Reference