Jasypt = Java Simplified Encryption
Spring에서 datasource를 연동할 때, application.yml 파일에 다음과 같이 설정할 수 있다.
spring:
datasource:
url: jdbc:mysql://...
username: user123
password: pass123
driver-class-name: com.mysql.cj.jdbc.Driver
이때 password와 같이 보안이 필요한 정보를 Commit시 외부에 공개되는 것을 막기 위해 암호화를 하는 것을 도와주는 도구다.
build.gradle에 dependency 추가
dependencies{
implementation group: 'com.github.ulisesbocchio',
name: 'jasypt-spring-boot-starter', version: '3.0.4'
}
코드 중 config.setPassword()메서드는 암호에 필요한 key 값을 넣는 것이다. 이 암호화 key 값에 따라 특정 String이 암호화가 된다.
- 암호화 key와 암호화하고자 하는 실제 password와 다르다
import lombok.RequiredArgsConstructor;
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;
import org.springframework.core.env.Environment;
@RequiredArgsConstructor
@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.setPassword("password");
config.setAlgorithm("PBEWithMD5AndDES");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
jasypt.encryptor.bean=jasyptStringEncryptor
jasypt.encryptor.algorithm=PBEWithMD5AndDES
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
ENC 안에 들어갈 코드는 직접 만들 수 있고 사이트를 이용할 수 있다.
String plainText = "hello";
String encryptText = encryptor.encrypt(plaintext)
위에서 만든 암호화된 텍스트로 암호화 하고싶은 정보를 ENC(텍스트) 형식으로 변환한다.
application.yaml파일 안에 ENC 값으로 넣어준다
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ENC(HkT6MzsagA1pP9RKYeZbMQMLx0tzhisPVCfydP4Ga3H8hB65Pk19qEDdpAyG+IEDT8Ofcxsstzk+alQc2gmsJ7OyPf+d9bkpcO6vYtmLJ+FpVS/NzNSGBd5bule8sOeQYhqkvcriSTg=)
username: ENC(j2POHa0PIgunJ31+DDuP2Q==)
password: ENC(9jqSM+xZZcDZpahr6sbRd1cA3ZAF7f4Z)
코드 실행 시 salt의 값을 Random하게 설정하여 매 번 실행시 encrypt text가 변경된다.
class JasyptTest {
@Test
public void jasypt_test() {
String plainText = "hello";
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("password");
config.setAlgorithm("PBEWithMD5AndDES");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
String encryptText = encryptor.encrypt(plainText);
System.out.println(encryptText);
String decryptText = encryptor.decrypt(encryptText);
System.out.println(decryptText);
assertThat(plainText).isEqualTo(decryptText);
}
}
docker run 실행시 환경변수를 지정하면 된다.
sudo docker run -it --name 컨테이너이름 -d -e password=비밀번호 -p PORT:PORT 이미지명
Dockerfile 엔트리 포인트 구성
ENTRYPOINT ["java","-jar","-Djasypt.encryptor.password=비밀번호","./Jar파일이름.jar"]