1. YML 암호화 (Jasypt)

보통 YML 파일에는 데이터베이스 암호, API 키, 서비스 계정 등의 중요한 정보가 저장되어 있다. 이런 정보들이 외부에서 노출되면 보안상의 문제가 발생할 수 있고, 심각한 피해를 입을 수 있다.

따라서 YML 파일에 저장된 중요한 정보들을 암호화해 보호함으로써 보안을 강화할 수 있다. 암호화된 정보는 외부에서 읽을 수 없고, 애플리케이션이 실행될 때 자동으로 복호화되어 사용할 수 있게 된다.

나는 YML 파일을 암호화하는 여러 방법 중 Jasypt 라이브러리를 사용하는 방법을 포스팅 하겟다.

  1. pom.xml에 의존성 추가
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.4</version>
</dependency>
  1. 암호화에 필요한 설정 추가 yml 파일

    jasypt:
      encryptor:
    	password: enckey
    	bean: **jasyptStringEncryptor** # Bean이름
    	algorithm: PBEWithMD5AndDES
    	    iv-generator-classname: org.jasypt.iv.NoIvGenerator
    

    여기에서 사용하는 Bean 이름은 아래 설정에 추가한 빈의 이름

    JasyptConfig

    @Configuration
    @RequiredArgsConstructor
    public class JasyptConfig {
    
    		// 서비스를 시작할 때 파라미터로 [-Djasypt.encryptor.password=패스워드] 형태로 넣어주면 패스워드 노출없이 실행 가능
        @Value("${jasypt.encryptor.password}")
        private String encryptKey;
    
        @Bean
        public StringEncryptor **jasyptStringEncryptor**() {
            PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
            SimpleStringPBEConfig config = new SimpleStringPBEConfig();
            config.setPassword(encryptKey);
            config.setPassword("password");
            config.setPoolSize("1");
            config.setProviderName("SunJCE");
            config.setAlgorithm("PBEWithMD5AndDES");
            config.setStringOutputType("base64");
            config.setKeyObtentionIterations("1000");
            config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
            encryptor.setConfig(config);
            return encryptor;
        }
    }
    
  2. 평문 암호화

    명령어 이용

    java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="비밀번호" password="암호화키" algorithm="암호화알고리즘" salt="salt값"
    

    테스트 코드 이용

    나는 이 방법으로 암호화된 문자열을 얻어 사용했다.

    @ExtendWith(SpringExtension.class)
    @SpringBootTest
    class JasyptConfigTest {
    
        @Autowired
        @Qualifier("jasyptStringEncryptor")
        StringEncryptor stringEncryptor;
    
        Logger logger = Logger.getAnonymousLogger();
    
        @Test
        public void jasyptTest() {
            logger.info(stringEncryptor.encrypt("암호화 할 문자열"));
            logger.info(stringEncryptor.encrypt("암호화 할 문자열"));
        }
    }
    
  3. 암호화된 문자열을 ENC(암호화된 문자열) 형식으로 YML에 작성

    spring:
    	datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          jdbc-url: jdbc:mysql://mysql-master:3306/myshop?serverTimezone=UTC&characterEncoding=UTF-8
          username: **ENC(1FAdTLjUqoFzcqVvng==)**
          password: **ENC(QEVZaiqZgQTVi9LEYA==)**
        slave:
          driver-class-name: com.mysql.cj.jdbc.Driver
          jdbc-url: jdbc:mysql://mysql-slave:3306/myshop?serverTimezone=UTC&characterEncoding=UTF-8
          username: **ENC(QGaczIPPNaFeex2+X44myw==)**
          password: **ENC(yQhp7qb/HXRoonabkqn05a==)**
    

2. Password 암호화 (BCrypt)

Untitled

패스워드는 사용자 인증 정보를 보호하기 위해 사용되며, 사용자 계정의 개인정보나 주요한 데이터에 접근하기 위한 수단이다.

만약 DB에 패스워드를 그대로 저장한다면, 패스워드가 노출되었을 때 중요한 데이터에 대한 접근이 가능하게 된다는 보안상의 약점이 나타난다.

따라서 DB에 저장 패스워드를 저장할 때는 암호화가 필수라고 할 수 있다. 암호화된 패스워드는 노출되어도 복호화가 불가능하기 때문에, 탈취자들이 중요한 데이터에 접근하지 못하도록 할 수 있다.

2.1. 암호화에 BCrypt를 사용한 이유

BCrypt 클래스는 암호화 라이브러리이며, 주로 비밀번호를 안전하게 저장하고 검증하는데 사용된다. 이 클래스는 단방향 해시 함수를 사용해 입력된 값을 암호화하고, 저장된 값을 비교해 입력된 값이 일치하는지 확인한다.

  1. 대칭키 암호화 방식과 비대칭키 암호화 방식은 복호화가 가능하다. 이는 보안성이 떨어질 수 있다는 단점이 있다.
  2. 단방향 해시 함수는 암호화된 결과를 복호화할 수 없다. 해시 함수를 사용하여 비밀번호를 저장하면, 해시된 결과를 저장하고, 저장된 해시값으로 비밀번호를 인증할 수 있다.
  3. BCrypt는 안전한 해시 알고리즘이다. 해시 함수의 문제점인 레인보우 공격과 무차별 대입 공격을 예방하기 위한 여러 가지 기술