728x90
반응형
개발에 있어서 매우 중요한 것 중 하나, 보안!

 

이전 팀 프로젝트와 개인 프로젝트에서는 아직 제대로 된 프로퍼티 암호화를 적용하지 않았어서

아이디와 비밀번호가 기재된 계정이나 DB 접속 정보와 같은 민감한 내용을

GitHub에 공백 또는 임의의 값으로 올리거나 .gitignore로 처리하는 번거로움이 있었다.

이번 개인 프로젝트에는 이 부분에 대한 개선을 위해 Jasypt를 활용한 프로퍼티 암호화를 적용해보아서 기록해 둔다.

 

Jasypt (Java Simplified Encryption)

Jasypt는 개발자가 암호화 작동 방식에 대한 깊은 지식이 없어도

최소한의 노력으로 프로젝트에 기본 암호화 기능을 추가할 수 있게 해주는 자바 라이브러리이다.

 

 

유튜브로 강의도 보고, 검색도 많이 해보았는데

대부분이 설명하는 글이라서 암호화하는 키(password)를

String = "my_key_value" 이런 식으로 프로퍼티 내부에 명시를 해두었는데

이럴 경우에 해당 값으로 누구나 디코딩이 가능하게 되어서 결국 암호화 한 의미가 없다.

더 나은 방법으로, 인텔리제이에서 JVM Option을 설정할 수 있어서

VM Option으로 값을 전달하는 방식으로 적용했다.


먼저 의존성을 추가해 준다. (gradle 기준)

implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.4'	// jasypt 의존성 추가 (프로퍼티 암호화)

Jasypt 설정 및 Bean 등록

package com.springproject.config;

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 password;

    @Bean(name = "jasyptStringEncryptor")
    public StringEncryptor stringEncryptor() {
//        String password = "비밀번호";    // VM Option으로 전달하는 방식이 더 안전해서 변경 적용 완료
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();

        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(password);   // 암호화할 때 사용하는 키
        config.setAlgorithm("PBEWithMD5AndDES");    // 암호화 알고리즘
        config.setKeyObtentionIterations("1000");   // 반복할 해싱 횟수
        config.setPoolSize("1");    // 인스턴스 pool
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");    // salt 생성 클래스
        config.setStringOutputType("base64");   // 인코딩 방식

        encryptor.setConfig(config);
        return encryptor;
    }
}

간단한 테스트에서는 위 내용에서 stringEncryptor() 내부에

주석처리된 password="비밀번호" 부분에 원하는 값을 넣어 key를 설정하면 되지만,

실제로 프로젝트에 적용하고자 하면 key 또한 별도로 감추어주는 것이 좋다.


프로퍼티 암호화

프로퍼티 암호화를 위해 암·복호화 사이트에 방문해서

① 암호화할 값을 입력

② Two Way Encryption(With Secret Text) 선택

③ Key값을 입력

마지막으로 Encrypt 버튼을 클릭하면 암호화 값을 확인할 수 있다.

 

아래 이미지는 암호화 사이트 모습으로

우측에 암호화된 값과 Key(password로 언급했던) 값을 넣어주면

암호화 전 원래의 값을 확인할 수 있다. (복호화)

암호화 사이트 모습(좌-암호화, 우-복호화)

Key 값은 잊어버리지 않도록 별도로 작성 후 저장해 두는 것이 좋다.


application.yml에 반영

실제로 프로젝트에 적용하기 위해 application.yml 파일 내 DB 접속정보 값을 ENC(암호화 값)로 수정한다. 

spring:
  datasource:
    url: ENC(zQVsiPgBkSc0hJ2pb/Gjf6D9xTou+FFqEE6Eb6hvWy9fJ3jO6LisA2hjK9LB52cL7LbZCs+EJqk=)
    username: ENC(yc/9dYuj6thDEZmI5/N5iA==)
    password: ENC(8HxW/0iGqW6VJtzhVoX3qw==)
    driver-class-name: com.mysql.cj.jdbc.Driver

VM Options 추가

-Djasypt.encryptor.password=암호화에 사용할 키 값


테스트 코드로 암호화 결과 확인해 보기

테스트 코드 실행 시에도 위 내용처럼 VM Options을 통해 암호화 Key값을 전달해 주어도 된다.

아래는 작성한 테스트 코드이다.

package com.springproject.config;

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class JasyptConfigTest {

    @Value("${jasypt.encryptor.password}")
    private String password;

    @Test
    void encryptTest() {
        String url = "enc_test_url";
        String id = "enc_test_id";
        String password = "enc_test_pw";

        System.out.println("db_url : " + jasyptEncoding(url));
        System.out.println("db_id : " + jasyptEncoding(id));
        System.out.println("db_password : " + jasyptEncoding(password));
    }

    public String jasyptEncoding(String value) {
        StandardPBEStringEncryptor pbeEnc = new StandardPBEStringEncryptor();
        pbeEnc.setAlgorithm("PBEWithMD5AndDES");
        pbeEnc.setPassword(password);
        return pbeEnc.encrypt(value);
    }
}

위 테스트 코드를 실행하여 암호화 된 값을 결과로 확인한다.

테스트 실행 결과

실행할 때 마다 결과 값은 항상 다르다.

Why?

Jasypt보안을 강화하기 위해 Salt 값을 사용한다,

Salt는 암호화된 데이터의 보안성을 높이기 위해 사용되며, 매번 실행할 때마다 랜덤한 Salt 값을 생성하여 데이터를 암호화한다.

이렇게 하면 동일한 데이터라도 매번 다른 암호화 결과가 생성된다.

(동일한 데이터에 대해 매번 같은 결과라면 암호화 의미가 없음!!)

 

 

참고 사이트
 

[Spring] Jasypt를 이용한 암호화

Jasypt는 자바에서 암호화를 쉽게 할 수 있도록 도와주는 라이브러리이다. When? Spring에서 datasource를 연동할 때, application.yml 파일에 다음과 같이 설정할 수 있다. spring: datasource: url: jdbc:mysql://... user

gksdudrb922.tistory.com

 

GitHub - ulisesbocchio/jasypt-spring-boot: Jasypt integration for Spring boot

Jasypt integration for Spring boot. Contribute to ulisesbocchio/jasypt-spring-boot development by creating an account on GitHub.

github.com

 

Jasypt: Java simplified encryption - Jasypt: Java simplified encryption - Main

Jasypt 1.9.3 RELEASED! (May 25th, 2019) [DOWNLOAD and ChangeLogs] [WHAT'S NEW IN JASYPT 1.9] 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 wi

www.jasypt.org

암호화/복호화 사이트 (Free)
 

Programming Blog Article Feeds as per your Interest | DevGlan

Best programming article feeds as per your Interest on different technologies. Subscribe to any technology and explore the best articles from around the web.

www.devglan.com

 

728x90
반응형

+ Recent posts