티스토리 뷰

반응형

Gradle 의존성

버전은 최신버전으로 추가한다.

dependencies {
    implementation group: 'com.github.ulisesbocchio', name: 'jasypt-spring-boot-starter', version: '3.0.4'
}

 

 

암호화 예시 코드

평문을 암호문으로 바꿔보겠다

import org.assertj.core.api.Assertions;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.TestConfiguration;

@TestConfiguration
class JasyptConfigTest {

    @Test
    void jasypt(){
        String password = "jerry-blog";

        String encryptPassword = jasyptEncrypt(password);

        System.out.println("encryptPassword : " + encryptPassword);

        //Assertions.assertThat(password).isEqualTo(jasyptDecryt(encryptPassword));
    }

    // 암호화 코드
    private String jasyptEncrypt(String input) {
        String key = "1234";
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(key);
        config.setPoolSize("1");
        config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        config.setStringOutputType("base64");
        config.setKeyObtentionIterations("1000");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        encryptor.setConfig(config);
        return encryptor.encrypt(input);

}

 

 

위 jasyptEncrypt 함수는 평문으로 작성된 password를 jasypt로 암호화하는 함수이다. 이때, 암호화하는 key를 1234로 하겠다. 이 키는 복호화할 때도 쓰이며 공개가 되면 안 되는 키이다. 이해를 돕기위해 지금 예시코드에는 key를 코드에 넣어 사용하겠다. 

 

jasyptEncrypt 함수의 input 파라미터로 평문을 받는다. 본인은 'jerry-blog'라는 평문을 암호화 할 것이다. key 변수에 암호화에 사용할 키를 지정한다. 본인은 1234라고 대충 넣었지만 당연히 암호화키는 이렇게 쉽게 지으면 안 된다. SimpleStringPBEConfig 객체를 생성 후 config 객체에 암호화에 필요한 설정을 지정한다. 설정은 아래와 같다.

1. config.setPassword(key) : 암호화/복호화에 사용할 비밀키를 설정
2. config.setPoolSize("1") : 암호화/복호화에 사용할 스레드 풀 크기 설정, 단일 스레드를 사용하므로 "1"로 설정
3. config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256") : 사용할 알고리즘 설정
4. config.setStringOutputType("base64") : 암호화된 문자열을 표현할 출력 형식 설정
5. config.setKeyObtentionIterations("1000") : 키를 생성하기 위해 알고리즘에 적용할 반복 횟수 지정, 이 값이 높을 수록 암호화된 문자열의 안전성이 높아짐
6. config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator") : 솔트 생성기 클래스 설정, 솔트는 암호화된 문자열의 보안을 강화하기 위해 사용되는 임의의 추가 데이터이다. 솔트 생성에 RandomSaltGenerator 클래스 사용
7. config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator") : 초기화 벡터(IV) 클래스 설정, IV는 암호화 알고리즘이 블록 단위로 작동할 때 사용되는 초기화 값이다.

 

이후 설정이 완료된 config 객체를 encryptor에 넣고 문자열을 암호화한다. 평문을 암호화하기 위해 Test 코드를 실행한다. 출력된 내용은 아래와 같다.

encryptPassword : j7X4ohszjwvCoDZ7f0Yl8o8d04UiQw+MZOCppmKF96TB6L2NEw7nfM7g4rNFAdJhnbE7NZj3KDTv5k2jrlXzwySP3XpyGBrpIF6gUgiUOpQ=
BUILD SUCCESSFUL in 32s
4 actionable tasks: 2 executed, 2 up-to-date

 

평문이 암호화되어 Base64 형식으로 출력되었다. 

 

 

 

 

 

 

복호화 예시 코드 

암호화된 것을 다시 복호화 시켜보겠다.

import org.assertj.core.api.Assertions;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.TestConfiguration;

@TestConfiguration
class JasyptConfigTest {

    @Test
    void jasypt(){
        String password = "jerry-blog";

        String encryptPassword = jasyptEncrypt(password);
        String decrytPassword = jasyptDecryt(encryptPassword);

        System.out.println("encryptPassword : " + encryptPassword);
        System.out.println("decrytPassword : " + decrytPassword);

        Assertions.assertThat(password).isEqualTo(jasyptDecryt(encryptPassword));
    }

    // 암호화 코드
    private String jasyptEncrypt(String input) {
        String key = "1234";
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(key);
        config.setPoolSize("1");
        config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        config.setStringOutputType("base64");
        config.setKeyObtentionIterations("1000");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        encryptor.setConfig(config);
        return encryptor.encrypt(input);
    }

    // 복호화 코드
    private String jasyptDecryt(String input){
        String key = "1234";
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(key);
        config.setPoolSize("1");
        config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        config.setStringOutputType("base64");
        config.setKeyObtentionIterations("1000");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        encryptor.setConfig(config);
        return encryptor.decrypt(input);
    }
}

 

처음 암호화 예시 코드에서 복호화 함수만 추가되었다. 암호화 했을때의 설정을 똑같이 복호화 설정에 지정한 후 실행시키면 아래와 같이 출력된다. 원래의 평문과 복호화된 문자를 비교했을 때 에러가 발생하지 않았으므로 암호화 후 복호화가 잘 된 것으로 간주한다.

encryptPassword : j7X4ohszjwvCoDZ7f0Yl8o8d04UiQw+MZOCppmKF96TB6L2NEw7nfM7g4rNFAdJhnbE7NZj3KDTv5k2jrlXzwySP3XpyGBrpIF6gUgiUOpQ=
decrytPassword : jerry-blog
BUILD SUCCESSFUL in 14s
4 actionable tasks: 1 executed, 3 up-to-date

 

 

 

프로젝트 적용

위 코드를 사용하여 암호화된 문구를 설정에 추가한 뒤 Bean에 넣어서 사용해 보겠다.

환경설정 파일에 암호화된 문구를 아래와 같이 지정해주자. 본인은 application.yaml에 추가하였다.

 

아래 코드는 jasypt 라이브러리를 문자열을 암호화하기 위한 빈을 생성하고, 이 해당 빈의 이름을 jasyptStringEncryptor라고 명명한다.

그리고 내가 지정하고 싶은 설정을 작성한다. 위에서 암호화 된 코드를 넣고 앞에 ENC(...)를 붙여줘야한다. ENC(...)를 붙이는 이유는 해당 값이 암호화 됐음을 알리기 위해서이다.

 

아래는 application.yaml의 내용이다.

jasypt:
  encryptor:
    bean: jasyptStringEncryptor
    
jerry:
  key: ENC(j7X4ohszjwvCoDZ7f0Yl8o8d04UiQw+MZOCppmKF96TB6L2NEw7nfM7g4rNFAdJhnbE7NZj3KDTv5k2jrlXzwySP3XpyGBrpIF6gUgiUOpQ=)

 

 

다음 인텔리제이 상단의 메뉴에서 [Run > Edit Configurations]를 클릭한다.

아래와 같은 화면이 나타나면 오른쪽에 [Modify options > Add VM options]를 클릭한다.

VM 옵션에 -DJASYPT.ENCRYPTOR.PASSWORD 옵션을 넣고 내가 지정할 비밀번호 1234를 넣는다.

 

앞에 -D를 붙여주는 것은 JVM에 직접 설정을 전달하기 위해서이다. JVM에 직접 전달한 설정값은 애플리케이션 코드에서 접근할 수 없기에 본인은 보안적으로 좀더 안전하다 판단했다. 보통은 -D 옵션을 빼고 넣는것이 일반적이긴하다.

 

이렇게 하면 암호화/복호화를 할 때 지정된 암호가 적용된다.

 

 

 

다음은 암호화 된 환경설정을 변수로 등록하겠다. 아래와 같은 클래스를 만들어준 뒤 암호화 된 문구를 가져오는 Bean을 등록한다.

 

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Profile(value = {"local"})
public class JasyptConfig {
    @Value("${jerry.key}")
    private String jerryKey;

    @Bean
    public String jerryKeyMethod() {
        // jerryKey 변수를 사용한 코드작성
    }
}

 

 

아래 예시와 같이 다른 클래스를 생성후, 위의 JasyptConfig 클래스 필드를 선언 한다. 그리고 jasyptConfig.jerryKeyMethod() 호출하여 암호화된 키를 이용한 함수를 사용할 수 있다. 

@Service
public class TestService {

  private final JasyptConfig jasyptConfig;
  
  String result = jasyptConfig.jerryKeyMethod();
}

 

jasypt 암호화 설정은 DB를 접속할 때 key를 암호화 등록해 둔다거나, API key와 같이 민감정보를 숨길 때 주로 사용한다. 

반응형
댓글
공지사항