[BE/4주차] 민감정보 암호화

Rare·2020년 8월 15일
1

backend

목록 보기
6/6
post-thumbnail

프로젝트를 진행하다 보면 공개된 repo에 업로드되면 안되는 민감 정보들이 있기 마련인데(예를 들어 RDS 엔드포인트, OAuth 2.0 client-secret 등등) 이와 같은 정보들은 암호화하여 업로드해야 한다. 우리들은 어떻게 민감 정보를 감출 것인지 여러 기술들을 검토했는데 그 중 jasypt로 하는 게 좋을 것 같아서 이 기술을 채택했다. (Spring Config Cloud 를 사용하려고 했는데 깃헙 저장소를 3개나 사용하더라...) 지금부터 Jasypt를 이용해서 민감 정보를 암호화해보자.

프로젝트를 만들면서 필요한 부분을 정리하고 있습니다.
모호하거나, 잘못된 부분이 있으면 댓글로 남겨주세요! 감사합니다 :)

0. 개발 스펙


  • SpringBoot 2.3.1 RELEASE
  • Gradle 6.4.1

1. build.gradle


다음 의존성을 추가한다.

compile group: 'com.github.ulisesbocchio', name: 'jasypt-spring-boot-starter', version: '3.0.3'

2. JasyptConfig.java


다음 클래스를 추가해준다.

@Configuration
public class JasyptConfig {

    @Bean("jasyptStringEncryptor")  // (1)
    public StringEncryptor stringEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword("hello");  // (2)
        config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        return encryptor;
    }
}

(1) jasypt 3.0 이상 버전을 사용한다면 'jasyptStringEncryptor'을 사용해주자. 공식 문서에는 'encryptorBean' 을 사용하기도 하는데 3.0 이상 버전에서 에러가 발생한다. 참고 사이트

(2) 자신이 암호화 할 때 설정한 시크릿 키를 넣어준다. 시크릿 키도 암호화하고 싶다면 시스템 환경변수로 설정해두고 가져다 쓰자. (밑에서 설명)

이로써 Jasypt에 관한 설정이 마무리가 됐다.
Jasypt 는 다양한 설정을 할 수 있도록 지원하고 있는데 초보자가 커스텀하게 설정해서 사용하기에는 어렵고 복잡하다. 그래서 'jasypt-spring-boot-starter' 를 제공하여 초보자도 간단하게 사용 할 수 있게 지원해주는 것 같다. 내가 커스텀하게 암호화 설정을 하고 싶다면 공식 문서를 참고하길 바란다.

3. 민감 정보 암호화


Jasypt를 사용하여 민감 정보를 암호화 하기 위해서는 다음과 같은 과정이 필요하다.

  1. 민감 정보 암호화하기
  2. 암호화 된 민감 정보 ENC 로 감싸서 application.properties(또는 application.yml)에 넣기

3.1 민감 정보 암호화하기 - 사이트 이용

민감 정보를 암호화 해주는 방법으로 CommandLineRunner 와 사이트 이용 등 여러 방법이 있는데 나는 민감 정보를 암호화 해주는 사이트를 이용했다.

사이트 이용 방법은 다음과 같다.

암호화(Encryption)

  1. 암호화 할 문자를 입력하세요

  2. 더 강화된 암호화를 위해 비대칭 암호화를 사용하려고 합니다. Two Way Encryption(With Secret Text) 를 선택해주세요

  3. 시크릿 키를 입력해주세요. 이 시크릿 키는 로그인 시 사용하는 ID/PWD 에서 PWD 같은 역할입니다. 시크릿 키를 모르면 복호화 할 수 없습니다. 참고로 이 키를 설정해주는 이유에 대해선 비대칭 암호화를 공부해주세요.

  4. 'Encrypt' 를 누른 뒤 성공하면 비대칭 암호화를 통해 암호화된 문자열이 나타납니다. 우리는 이 문자열을 코드에 삽입 할 겁니다.

복호화(Decryption)

  1. 비대칭 암호화를 통해 암호화된 문자열을 넣어줍니다.

  2. 비대칭 암호화를 했을 경우 Decrypt Password 를 선택합니다

  3. 시크릿 키를 입력합니다. 암호화를 했을 때 넣어주었던 시크릿 키를 넣어줍니다.

  4. Match/Decrypt 가 성공했을 때 복호화 된 문자열이 담깁니다. 시크릿 키가 올바르지 않으면 복호화되지 않습니다.


3.2 암호화 된 민감 정보를 ENC로 감싸고 사용하기

암호화 할 내용을 만들었다면 다음과 같이 설정 파일에 작성해줍니다.

spring:
  datasource:
  url: ENC(YWG87FUr+PNX6IdWon9E124+h0uKmbfLEwDggm6YvWo=)
  username: ENC(i1f8YG+iTZfS7VpbiyDf6TXwYFc4Vjdv)
  password: ENC(uI9wv96P4imrilc9EqQBPHwOk5bGmNoq)

어떤 값이 적혀 있는지 겉으로는 모르지만 jasypt 는 프로그램 구동 시 암호화 된 설정들을 복호화하여 프로그램 구동에 문제가 없게 합니다.

그리고 코드에서 이 값을 사용하고 싶다면 @Value 애노테이션으로 값을 불러와서 사용하면 됩니다.

public class RareService {
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String user;
    @Value("${spring.datasource.password}")
    private String password;
    // 비즈니스 로직...
}

4. JasyptConfig 클래스에 있는 시크릿 키를 암호화하고 싶다면


  1. 시스템 환경 변수에 시크릿 키를 등록해준다
    • export JASYPT_PASSWORD =hello
  2. System 클래스의 getEnv() 메서드를 이용하여 시스템 환경 변수를 불러온다
    • System.getenv("JASYPT_PASSWORD");
  3. 완성 형태
public StringEncryptor stringEncryptor() {
    PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
    SimpleStringPBEConfig config = new SimpleStringPBEConfig();
    config.setPassword(System.getenv("JASYPT_PASSWORD");
    // ...
}

5. 문제 발생


Jasypt 를 적용 후 CodeDeploy 로 서버에 자동 배포될 때 EC2 에서 자동 배포가 제대로 돌지 않는 이슈가 발생했다. 그리고 Windows 로컬 터미널로 프로젝트 jar 파일을 구동했을 때 구동되지 않는 이슈 도 발생했다. (맥에선 구동이 됨) 그래서 한참 트러블슈팅하다가 도저히 해결 할 수 없어서 결국 Jasypt를 버리고 시스템 환경 변수로 암호화를 하기로 했다.

6. Jasypt 로 암호화한 문자열을 모두 시스템 환경 변수로 설정


당장 다른 암호화 기술을 사용하여 민감 정보를 암호화 할 수 없어서 차선책으로 시스템 환경 변수를 설정하여 사용했다. 이 방법의 사용법은 다음과 같다.

  1. 사용 할 값을 시스템 환경 변수에 등록합니다
  2. application.yml 에 등록한 환경 변수를 ${환경_변수_명} 형식으로 적절히 적어줍니다.
  3. 완성 형태
spring:
  datasource:
    url: ${DB_URL}
    username: ${DB_USER}
    password: ${DB_PWD}

7. 참고사이트


profile
블로그 서비스 ‘레어’ 기술 블로그

0개의 댓글