이 방식은 DB 접속 정보나 API 키 등 민감한 정보를 소스 코드나 설정 파일에 평문으로 노출시키지 않고 안전하게 관리하는 매우 효과적인 방법입니다.
작업 절차
- Jasypt 라이브러리 의존성 추가
- 암호화 키(Secret Key) 설정
- 암호화된 값 생성
application.properties에 암호화된 값 적용- Jasypt 설정 클래스 작성 (선택 사항이지만 권장)
- 테스트 및 확인
1. Jasypt 라이브러리 의존성 추가
build.gradle 파일에 Jasypt Spring Boot Starter 의존성을 추가합니다. 이 스타터가 대부분의 자동 설정을 처리해 줍니다.
build.gradle
|
1 2 3 4 5 6 |
<span class="line"><span>dependencies {</span></span> <span class="line"><span> // ... 다른 의존성들</span></span> <span class="line"><span> </span></span> <span class="line"><span> // Jasypt for Spring Boot</span></span> <span class="line"><span> implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5'</span></span> <span class="line"><span>}</span></span> |
참고: 최신 버전은 Maven Central에서 확인하여 적용하는 것이 좋습니다.
2. 암호화 키(Secret Key) 설정
암호화와 복호화를 위해서는 **비밀 키(Secret Key)**가 필요합니다. 이 키는 절대 소스 코드나 application.properties에 직접 노출해서는 안 됩니다. **환경 변수(Environment Variable)**나 JVM 옵션으로 주입하는 것이 가장 안전하고 권장되는 방법입니다.
방법 A: 환경 변수로 설정 (가장 추천)
운영체제의 환경 변수로 키를 설정합니다.
- Linux/macOS:
Bash1<span class="line"><span>export</span><span> JASYPT_ENCRYPTOR_PASSWORD</span><span>=</span><span>"your-super-secret-key"</span></span>
- Windows:
PowerShell1<span class="line"><span>$env:JASYPT_ENCRYPTOR_PASSWORD="your-super-secret-key"</span></span>
방법 B: JVM 옵션으로 설정
애플리케이션 실행 시 JVM 옵션으로 키를 전달합니다.
|
1 |
<span class="line"><span>java</span><span> -Djasypt.encryptor.password=</span><span>"your-super-secret-key"</span><span> -jar</span><span> your-app.jar</span></span> |
- IDE(IntelliJ 등)에서 실행할 때는 ‘Run/Debug Configurations’의 ‘VM options’에
-Djasypt.encryptor.password="your-super-secret-key"를 추가하면 됩니다.
your-super-secret-key 부분에는 복잡하고 예측하기 어려운 실제 비밀 키를 사용해야 합니다.
3. 암호화된 값 생성
이제 설정한 비밀 키를 사용하여 application.properties에 넣을 값을 암호화해야 합니다. Jasypt는 이를 위한 간단한 방법을 제공합니다.
온라인 암호화 도구 사용 (간편):
- Jasypt Online Encryptor 같은 웹사이트를 이용하면 편리합니다.
- Password: 2단계에서 설정한
your-super-secret-key를 입력합니다. - Text to Encrypt: 암호화할 평문(예:
my_db_password)을 입력합니다. - Encrypt 버튼을 누르면 암호화된 값(예:
xsxxxxxxxxxxxxxx)이 생성됩니다.
Java 코드로 생성 (프로젝트 내에서):
테스트 코드 등을 활용하여 직접 암호화할 수도 있습니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span class="line"><span>import</span><span> org.jasypt.encryption.pbe.StandardPBEStringEncryptor;</span></span> <span class="line"></span> <span class="line"><span>public</span><span> class</span><span> JasyptEncryptor</span><span> {</span></span> <span class="line"><span> public</span><span> static</span><span> void</span><span> main</span><span>(</span><span>String</span><span>[] </span><span>args</span><span>) {</span></span> <span class="line"><span> StandardPBEStringEncryptor encryptor </span><span>=</span><span> new</span><span> StandardPBEStringEncryptor</span><span>();</span></span> <span class="line"><span> encryptor.</span><span>setPassword</span><span>(</span><span>"your-super-secret-key"</span><span>); </span><span>// 1. 비밀 키 설정</span></span> <span class="line"><span> encryptor.</span><span>setAlgorithm</span><span>(</span><span>"PBEWithMD5AndDES"</span><span>); </span><span>// 2. 알고리즘 설정 (Jasypt 기본값)</span></span> <span class="line"></span> <span class="line"><span> String plainText </span><span>=</span><span> "my_db_password"</span><span>; </span><span>// 3. 암호화할 평문</span></span> <span class="line"><span> String encryptedText </span><span>=</span><span> encryptor.</span><span>encrypt</span><span>(plainText); </span><span>// 4. 암호화 실행</span></span> <span class="line"></span> <span class="line"><span> System.out.</span><span>println</span><span>(</span><span>"Encrypted Text: "</span><span> +</span><span> encryptedText);</span></span> <span class="line"><span> </span></span> <span class="line"><span> // 복호화 테스트</span></span> <span class="line"><span> // String decryptedText = encryptor.decrypt(encryptedText);</span></span> <span class="line"><span> // System.out.println("Decrypted Text: " + decryptedText);</span></span> <span class="line"><span> }</span></span> <span class="line"><span>}</span></span> |
4. application.properties에 암호화된 값 적용
이제 암호화된 값을 ENC() 래퍼로 감싸서 application.properties 파일에 적용합니다.
src/main/resources/application.properties
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="line"><span># 데이터베이스 접속 정보</span></span> <span class="line"><span>spring.datasource.url=jdbc:mysql://localhost:3306/mydb</span></span> <span class="line"><span>spring.datasource.username=db_user</span></span> <span class="line"><span></span></span> <span class="line"><span># ✅ 비밀번호를 암호화하여 저장</span></span> <span class="line"><span># Jasypt는 ENC(...) 패턴을 감지하고 자동으로 괄호 안의 값을 복호화합니다.</span></span> <span class="line"><span>spring.datasource.password=ENC(aBcDeFgHiJkLmNoPqRsTuVwXyZ12345==)</span></span> <span class="line"><span></span></span> <span class="line"><span># 외부 API 키</span></span> <span class="line"><span>my.api.secret-key=ENC(zYxWvUtSrQpOnMlKjIhGfEdCbA54321==)</span></span> <span class="line"><span></span></span> <span class="line"><span># Jasypt가 비밀 키를 어디서 읽어올지 명시 (선택사항이지만 명확성을 위해 추천)</span></span> <span class="line"><span># ${JASYPT_ENCRYPTOR_PASSWORD}는 환경 변수를 의미함</span></span> <span class="line"><span>jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD}</span></span> |
5. Jasypt 설정 클래스 작성 (선택사항이지만 권장)
대부분의 경우 Jasypt 스타터가 자동 설정을 해주지만, 암호화 알고리즘을 변경하거나, 키를 가져오는 방식을 커스텀하는 등 세밀한 제어를 위해 설정 클래스를 직접 만드는 것이 좋습니다.
JasyptConfig.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<span class="line"><span>package</span><span> com.example.demo.config;</span></span> <span class="line"></span> <span class="line"><span>import</span><span> org.jasypt.encryption.StringEncryptor;</span></span> <span class="line"><span>import</span><span> org.jasypt.encryption.pbe.PooledPBEStringEncryptor;</span></span> <span class="line"><span>import</span><span> org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;</span></span> <span class="line"><span>import</span><span> org.springframework.beans.factory.annotation.Value;</span></span> <span class="line"><span>import</span><span> org.springframework.context.annotation.Bean;</span></span> <span class="line"><span>import</span><span> org.springframework.context.annotation.Configuration;</span></span> <span class="line"></span> <span class="line"><span>@</span><span>Configuration</span></span> <span class="line"><span>public</span><span> class</span><span> JasyptConfig</span><span> {</span></span> <span class="line"></span> <span class="line"><span> // application.properties 또는 환경 변수로부터 비밀 키를 주입받음</span></span> <span class="line"><span> @</span><span>Value</span><span>(</span><span>"${jasypt.encryptor.password}"</span><span>)</span></span> <span class="line"><span> private</span><span> String encryptKey;</span></span> <span class="line"></span> <span class="line"><span> @</span><span>Bean</span><span>(</span><span>"jasyptStringEncryptor"</span><span>) </span><span>// Bean의 이름을 명확히 지정</span></span> <span class="line"><span> public</span><span> StringEncryptor </span><span>stringEncryptor</span><span>() {</span></span> <span class="line"><span> PooledPBEStringEncryptor encryptor </span><span>=</span><span> new</span><span> PooledPBEStringEncryptor</span><span>();</span></span> <span class="line"><span> SimpleStringPBEConfig config </span><span>=</span><span> new</span><span> SimpleStringPBEConfig</span><span>();</span></span> <span class="line"><span> </span></span> <span class="line"><span> config.</span><span>setPassword</span><span>(encryptKey); </span><span>// 1. 비밀 키 설정</span></span> <span class="line"><span> config.</span><span>setAlgorithm</span><span>(</span><span>"PBEWithMD5AndDES"</span><span>); </span><span>// 2. 암호화 알고리즘</span></span> <span class="line"><span> config.</span><span>setKeyObtentionIterations</span><span>(</span><span>"1000"</span><span>); </span><span>// 3. 해싱 반복 횟수</span></span> <span class="line"><span> config.</span><span>setPoolSize</span><span>(</span><span>"1"</span><span>); </span><span>// 4. 인크립터 풀 사이즈</span></span> <span class="line"><span> config.</span><span>setProviderName</span><span>(</span><span>"SunJCE"</span><span>);</span></span> <span class="line"><span> config.</span><span>setSaltGeneratorClassName</span><span>(</span><span>"org.jasypt.salt.RandomSaltGenerator"</span><span>);</span></span> <span class="line"><span> config.</span><span>setStringOutputType</span><span>(</span><span>"base64"</span><span>);</span></span> <span class="line"><span> </span></span> <span class="line"><span> encryptor.</span><span>setConfig</span><span>(config);</span></span> <span class="line"><span> return</span><span> encryptor;</span></span> <span class="line"><span> }</span></span> <span class="line"><span>}</span></span> |
- 이 설정 클래스를 만들면, Jasypt는 자동 설정 대신 이 Bean을 사용하여 암/복호화를 수행합니다.
6. 테스트 및 확인
이제 애플리케이션을 실행하고, 암호화된 값이 필요한 Bean이 제대로 주입되고 동작하는지 확인합니다.
예를 들어, 데이터베이스 커넥션이 정상적으로 맺어지는지 확인하거나, API 키를 사용하는 서비스가 잘 동작하는지 테스트합니다.
테스트용 Controller 예시:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="line"><span>@</span><span>RestController</span></span> <span class="line"><span>public</span><span> class</span><span> TestController</span><span> {</span></span> <span class="line"></span> <span class="line"><span> @</span><span>Value</span><span>(</span><span>"${my.api.secret-key}"</span><span>)</span></span> <span class="line"><span> private</span><span> String secretKey;</span></span> <span class="line"></span> <span class="line"><span> @</span><span>GetMapping</span><span>(</span><span>"/get-key"</span><span>)</span></span> <span class="line"><span> public</span><span> String </span><span>getApiKey</span><span>() {</span></span> <span class="line"><span> // 이 secretKey 변수에는 복호화된 평문 값이 들어있게 됩니다.</span></span> <span class="line"><span> // 예: "my-super-secret-api-key"</span></span> <span class="line"><span> return</span><span> "Decrypted API Key: "</span><span> +</span><span> secretKey;</span></span> <span class="line"><span> }</span></span> <span class="line"><span>}</span></span> |
애플리케이션을 실행하고 http://localhost:8080/get-key에 접속했을 때, 암호화되기 전의 원래 API 키 값이 출력된다면 성공적으로 설정된 것입니다.
이 과정을 통해 민감한 정보를 Git과 같은 버전 관리 시스템에 노출하지 않으면서도, 애플리케이션은 정상적으로 해당 값을 사용할 수 있는 안전한 환경을 구축할 수 있습니다.