Programming/스프링 부트(Spring Boot)
[Spring Boot] - jasypt 을 사용하여 암/복호화 하기
귀찮은 개발자
2024. 2. 20. 13:09
jasypt란
양방향 암호화를 사용할 수 있는 Java 라이브러리이다.
시스템 환경변수와 마찬가지로 소스코드가 외부에 반출되더라도 중요한 Access/Secret key 등 중요한 정보가 평문으로 노출되는 것을 방지하고자 하는 목적으로 사용된다.
Dependency 추가 방법
Maven
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
Gradle
implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.4'
Jasypt 설정 및 Bean 등록
System.getenv("ENCRYPTOR_PASSWORD"); 라고 작성되어 있는 부분이 암호화된 ENC 을 디코딩하기 위한 Key 이다.
java -jar 명령어를 사용하여 시스템 환경변수 ENCRYPTOR_PASSWORD 에 value 을 저장하여 사용한다.
JasyptConfig Been 등록
package com.wable.user_api.global.config;
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
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;
@Configuration
@EnableEncryptableProperties
public class JasyptConfigAES {
@Bean("jasyptEncryptorAES")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
String jasyptPassword = System.getenv("ENCRYPTOR_PASSWORD");
config.setPassword(jasyptPassword); // 암호화키
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;
}
}
application.properties
cloud:
...
private:
group:
secretKey: ENC(iGUPWEyRfu6vTBYdFeAa91gXWRpxAObYy9eSxZC8mlACtWTFFocdRj/ajb2BjZ//CvZXbNZkEtupSUZja4Quo5CF5Y03eauouKayLTBEwETy4w6w3WY9i0cVpT0UrpytZjsjdoWj+FwrQxgp5kcJ4w==)
validityMillis: ENC(8aPdvU+zDbp/VUAcQTx/L83Q5+WNwo0kA8D5bAjrY1OtbcnX+mi1fIE5l1TmYqZS)
@value 어노데이션 사용 시
@Component
public class TokenGenerator {
@Value("${cloud.private.group.secretKey}")
private String secretKey;
@Value("${cloud.private.group.validityMillis}")
private long validityMillis;
public String generateJwtToken() {
long nowMillis = System.currentTimeMillis();
long expMillis = nowMillis + validityMillis;
return Jwts.builder()
.setExpiration(new Date(expMillis))
.signWith(SignatureAlgorithm.HS256, secretKey.getBytes())
.compact();
}
테스트를 통해 암호화 Value 생성
package com.wable.user_api.domain.card.repository;
import io.jsonwebtoken.security.Keys;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.iv.RandomIvGenerator;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import java.util.Date;
class JasyptConfigAESTest {
@Test
void stringEncryptor() {
String url = "jdbc:mysql://localhost:3306/default";
String username = "root";
String password = "password";
System.out.println("ENC(" + jasyptEncoding(url) + ")");
System.out.println("ENC(" + jasyptEncoding(username) + ")");
System.out.println("ENC(" + jasyptEncoding(password) + ")");
}
public String jasyptEncoding(String value) {
String jasyptPassword = System.getenv("ENCRYPTOR_PASSWORD");
System.out.println(jasyptPassword);
StandardPBEStringEncryptor pbeEnc = new StandardPBEStringEncryptor();
pbeEnc.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
pbeEnc.setPassword(jasyptPassword);
pbeEnc.setIvGenerator(new RandomIvGenerator());
return pbeEnc.encrypt(value);
}