설정파일 암호화
보통 Spring 프로젝트를 진행하면 application.yml(.propertise)파일을 이용해 프로젝트 설정을 관리하게 되고, DB Connection 관련 부분도 다음과 같이 작성하게 된다.
spring:
output:
ansi:
enabled: always
datasource:
url: jdbc:mariadb://(서버주소):3306/(DB명)
username: (id)
password: (pw)
driver-class-name: org.mariadb.jdbc.Driver
jpa:
hibernate:
ddl-auto: none #create , create-drop , update , validate, none
properties:
hibernate:
show_sql: true
format_sql: true
로컬 DB만으로 작업한다면 서버주소에 lcoalhost를 넣어버리면 되니까, github과 같은 저장소에 id와 pw가 유출되어도 치명적으로 작용하지는 않을 것이다. 하지만, 배포를 하거나, 외부 DB에 접근하는 경우에 id, pw, 서버주소까지 노출하게 된다면, 외부 공격을 당할 가능성이 열려있기 때문에 위험하다.
아무튼! 이런 이유로 id와 pw를 암호화 하여 설정파일을 관리하도록 하자.
일단 암호화해줄 라이브러리를 추가해주도록 하자.
compile (group: 'com.github.ulisesbocchio', name: 'jasypt-spring-boot-starter', version: '2.1.1')
compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.61'
암호화/복호화 해줄 Config 클래스가 필요하다.
설정 클래스에 @EnableEncryptableProperties를 추가해주고, 암호화 알고리즘과 키(Password)값을 지정해 주도록 하자.
@Configuration
@EnableEncryptableProperties
public class PropertyEncryptConfig {
@Bean("encryptorBean")
public PooledPBEStringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setProvider(new BouncyCastleProvider());
encryptor.setPoolSize(2);
encryptor.setPassword("MySecretKey");
encryptor.setAlgorithm("PBEWithSHA256And128BitAES-CBC-BC");
return encryptor;
}
}
테스트 코드에서 잘 암/복호화가 되는지 확인해 보도록 하자
@SpringBootTest
public class EncryptTest {
@Test
public void checkEncrypt(){
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setProvider(new BouncyCastleProvider());
encryptor.setPoolSize(2);
encryptor.setPassword("MySecretKey");
encryptor.setAlgorithm("PBEWithSHA256And128BitAES-CBC-BC");
String plainText = "root"; // 암호화 할 내용
String encryptedText = encryptor.encrypt(plainText); // 암호화
String decryptedText = encryptor.decrypt(encryptedText); // 복호화
System.out.println("Enc:"+encryptedText+", Dec:"+decryptedText);
}
}
출력 내용 : Enc:7WaPANUsZ2BgChaav82ZBgMzJ4LY5a2z9d6SKAB+Y2LpWxWPvFoQAPrMUoGhi6m8, Dec:root
위와같이 출력되면 성공이다. 암호화 할 문자열을 plainText에 넣어서 암호화 시키고, yml파일에 다음과 같이 사용하면 된다
jasypt:
encryptor:
bean: encryptorBean
username: ENC(tB5rllJdNVCnHIgiYnIZ+nfS5yhqBCYag0q+egT4pS+UngjSmOK7aacPO0/ObecK)
password: ENC(k0SQ5Ypj/86aDM+snjlgI5Ox+3OAgu7Xh6db6y6L3ikLMFcD7jNfxfZtrhfNlcnT)
이런식으로 작성하면 잘 실행되는 것을 확인할 수 있다.
하지만 과연 안전하다고 할 수 있을까??? 이렇게만 하고 끝낸다면, 문을 자물쇠로 잠궈놓고 열쇠를 문 앞에 두고가는 것과 다름이 없다. 암호화 설정 내용이 담긴 클래스와 암호화 된 내용이 담긴 yml 파일이 노출되기 때문에 그대로 가져다가 쓰면, 뚫리는 건 매한가지이다.
실제 배포환경에서는 민감정보는 ${"ValueName"} 같은 방식으로 설정 파일에 작성하고, 서버 단에서 값을 넣어주는 방식을 활용한다. AWS Secret Manager를 이용해서 설정파일의 값을 안전하게 관리할 수 있다고 한다. 참고로 30일만 무료라고 한다.
[참고 링크] : goateedev.tistory.com/131
'[IT] > SpringBoot' 카테고리의 다른 글
[Spring Boot] 테스트 데이터 생성 (.sql 실행) (0) | 2021.04.29 |
---|---|
[Spring Boot] Controller - Dto 유효성 검사 (0) | 2021.04.19 |
[Spring Boot] Junit5 테스트 순서 지정 (0) | 2021.04.18 |
[Spring Boot] JPA metamodel must not be empty 에러 (0) | 2021.04.16 |
[Data JPA & Query DSL] Repository의 구현클래스 선정 규칙 (0) | 2021.04.03 |