Spring 프로젝트의 Properties 파일에는 DB 연결정보, 이메일 계정, API Key 등의 보안에 민감한 정보들이 포함될 수 있습니다.
이 상태에서 프로젝트를 그대로 공유하게 되면 보안에 심각한 문제가 생길 수 있습니다.
이를 방지하기 위해 Spring 프로젝트에서 jasypt-spring-boot의 비밀번호 기반 암호화를 이용하여 중요한 정보들을 암호화하는 방법을 설명합니다.
참고
https://github.com/ulisesbocchio/jasypt-spring-boot
Dependency 추가
프로젝트의 pom.xml에 다음 Dependency를 추가합니다.
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
Property 설정
적용 및 테스트를 위해 application.properties에 다음과 같이 비밀번호를 작성합니다.
(실사용 시에는 비밀번호를 프로퍼티에서 삭제해주세요)
jasypt.encryptor.password=ExamplePassword123
-주의-
위처럼 비밀번호를 프로퍼티에 작성할 경우 결과적으로 비밀번호가 노출되기 때문에 보안 효과가 없습니다.
테스트 외에 실제 서비스에서 사용한다면 꼭 프로퍼티 파일 내 비밀번호를 삭제하고
비밀번호를 시스템 변수나 환경 변수에 등록하여 사용하시기를 권장합니다.
필수 프로퍼티는 jasypt.encryptor.password 밖에 없으며
이 외에 추가할 수 있는 프로퍼티는 다음과 같습니다.
작성하지 않으면 아래의 기본값이 적용됩니다.
자세한 내용은
https://github.com/ulisesbocchio/jasypt-spring-boot에서 확인해주세요.
jasypt.encryptor.algorithm=PBEWITHHMACSHA512ANDAES_256
jasypt.encryptor.key-obtention-iterations=1000
jasypt.encryptor.pool-size=1
jasypt.encryptor.provider-name=SunJCE
jasypt.encryptor.provider-class-name=null
jasypt.encryptor.salt-generator-classname=org.jasypt.salt.RandomSaltGenerator
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.RandomIvGenerator
jasypt.encryptor.string-output-type=base64
jasypt.encryptor.proxy-property-sources=false
jasypt.encryptor.skip-property-sources=empty list
사용하기
테스트 작성
테스트 유닛을 작성하여 암복호화가 작동하는지 확인해봅니다.
@SpringBootTest
public class JasyptTests {
@Autowired
StringEncryptor configurationEncryptor;
static final String TEST_PASSWORD = "테스트용 비밀번호 입니다.";
@Test
public void encryptTest() {
String encryptedPassword = configurationEncryptor.encrypt(TEST_PASSWORD);
System.out.println("encrypted password is : " + encryptedPassword);
String decryptedPassword = configurationEncryptor.decrypt(encryptedPassword);
assertThat(decryptedPassword).isEqualTo(TEST_PASSWORD);
}
}
테스트가 성공하면 콘솔에서 아래와 비슷한 암호화된 문자열을 확인할 수 있습니다.
encrypted password is : cA8DhDVl27MeHDSQRn8GSfUFGn+Qif2n9Zv8OLlq67yiijVJTe0wqwzRE9eIBSlfNQ5HeYirCXMZFwXPbO7LAHe+q/PeWxNcYE9Tr1LeBEs=
프로퍼티에 적용
공개되면 안 되는 프로퍼티 값을 암호화한 후 아래와같이 ENC()로 감싸서 작성하게 되면 프로퍼티를 불러올 때 자동으로 복호화하여 적용합니다.
test=ENC(cA8DhDVl27MeHDSQRn8GSfUFGn+Qif2n9Zv8OLlq67yiijVJTe0wqwzRE9eIBSlfNQ5HeYirCXMZFwXPbO7LAHe+q/PeWxNcYE9Tr1LeBEs=)
여기까지 적용하게 되면 프로퍼티 파일 노출로 인한 정보 노출을 방지할 수 있습니다.
프로퍼티를 불러올 때 정상적으로 복호화가 되는지 테스트를 위해
위의 JasyptTests 클래스에 다음과 같이 테스트코드를 추가하였습니다.
@SpringBootTest
public class JasyptTests {
...
@Value("${test}")
String test;
@Test
public void propertyTest() {
System.out.println("test password is : " + test);
assertThat(test).isEqualTo(TEST_PASSWORD);
}
}
테스트 정상적으로 완료되었다면 콘솔에서 복호화된 문자열을 확인할 수 있습니다.
test password is : 테스트용 비밀번호 입니다.
플러그인
위의 방식으로 민감한 정보들은 전부 암호화하여 사용하는 걸로도 충분하지만
플러그인과 메이븐 명령어를 이용하여 간단하게 암호화하는 방법을 소개합니다.
이를 위해서는 메이븐 명령어를 사용 가능해야 하며 메이븐 명령어의 기본적인 사용 방법은 다른 가이드를 참고해 주시길 바랍니다.
플러그인 추가
우선 플러그인 사용을 위해 pom.xml에 플러그인을 추가합니다.
<plugin>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-maven-plugin</artifactId>
<version>3.0.2</version>
</plugin>
프로퍼티 작성
프로퍼티를 작성할 때 암호화되지 않은 정보들을 DEC()로 감싸서 작성하게 되면 플러그인을 이용하여 일괄적으로 암호화 할 수 있습니다.
test=DEC(암호화되지 않은 테스트 프로퍼티 입니다.)
명령어를 이용하여 암복호화
콘솔에서 아래의 명령어로 application.properties 파일 내 DEC()로 감싸진 정보들을 일괄적으로 암호화 할 수 있습니다.
환경변수에 jasypt.encryptor.password를 등록해 놨다면 아래의 명령어에서 생략 가능합니다.
mvn jasypt:encrypt -Djasypt.encryptor.password="ExamplePassword123"
역으로 복호화도 가능합니다.
mvn jasypt:decrypt -Djasypt.encryptor.password="ExamplePassword123"
이를 이용하면 암호화된 정보를 좀 더 쉽게 수정하고 다시 암호화가 가능합니다.
프로퍼티 파일 지정하기
위처럼 명령어를 이용하면 application.properties가 아닌 application-test.properties 같은 파일은 암복호화가 되지 않습니다.
다른 파일을 암복호화 하고 싶을 경우 jasypt.plugin.path 파라미터로 파일을 지정할 수 있습니다.
mvn encrypt:encrypt -Djasypt.encryptor.password="ExamplePassword123" -Djasypt.plugin.path="file:src/main/test/application-dev.properties"
단독 값 암복호화 하기
아래의 명령어로 프로퍼티 파일과 별개로 단독 문자열을 암호화하거나 복호화가 가능합니다.
mvn jasypt:encrypt-value -Djasypt.encryptor.password="ExamplePassword123" -Djasypt.plugin.value="theValueYouWantToEncrypt"
mvn jasypt:decrypt-value -Djasypt.encryptor.password="ExamplePassword123" -Djasypt.plugin.value="DbG1GppXOsFa2G69PnmADvQFI3esceEhJYbaEIKCcEO5C85JEqGAhfcjFMGnoRFf"