Spring Cloud Config 설정 파일의 암호화 처리 : 비대칭키를 이용한 암/복호화)

Jiwon Jung·2023년 4월 30일
0
post-thumbnail

스프링 클라우드로 프로젝트를 진행해보고 있으며, 설정 파일을 암호화하는 방법을 알려드리고자 합니다.

간단하게 이론 개념 설명 진행 후 바로 사용 방법을 작성하겠습니다.

Spring Cloud Config Server는 실행 시 yml 같은 환경 설정 파일들을 애플리케이션이 실행할 때 전파합니다. 이런 설정 파일은 보안과 관련된 정보를 가지므로 암호화하여 안전하게 관리할 필요가 있습니다.

일반적으로 암/복호화하는 방식을 크게 대칭키 방식과 비대칭키 방식이 있습니다.

대칭키(Symmetric): 암/복호화하는 키가 동일한 경우입니다.
대표적으로 AES, SEED, ARIA와 같은 알고리즘이 있습니다.

비대칭키(Asymmetric): 암/복호화하는 키가 다른 경우를 의미합니다. 모든 사람이 사용할 수 있는 공개키(public key)와 공개키를 통해 암호화된 데이터를 복호화할 수 있는 개인키(private key)로 구분됩니다.
대표적으로 RSA 알고리즘이 있습니다.

Java Key Store를 이용해 키를 관리

Java는 Java Cryptography Extension(JCE)을 이용해 암호 관련 기능을 제공합니다. Java 11이상부터는 기본적으로 제공하고 있으며 그 밑 버전에서는 해당 라이브러리를 다운받아야 사용이 가능하다.

Java Key Store(JKS)는 JCE를 이용해 만든 키를 저장하고 관리하는 저장소라고 보시면 됩니다.


이제부터 RSA 알고리즘을 이용한 비대칭키 암/복호화 방식을 보여드리겠습니다.
참고로 현재 저는 Java 11, Spring Boot 2.7, MAC 환경입니다.

1. key pair 생성 될 폴더 디렉토리 생성

키를 저장하기를 원하는 디렉토리를 생성해보겠습니다.
저는 keystore 라는 이름의 디렉토리 생성했습니다.

mkdir keystore 

2. key pair를 생성

참고: genkeypair: 키페어 생성(generate)

아래의 명령어로 key pair를 생성합니다.

keytool -genkeypair -alias {별칭} -keyalg {key알고리즘} -dname "{소프트웨어 서면 정보들}" -keypass "{키 비밀번호}" -keystore {키 스토어이름}.jks -storepass "{키스토어 비밀번호}"

keytool -genkeypair -alias apiEncryptionKey -keyalg RSA -dname "CN=Jiwon Jung, OU=API Development, O=test.co.kr, L=Seoul, C=KR" -keypass "test1234" -keystore apiEncryption.jks -storepass "test1234"

위 명령어 입력하면, 생성되었다고 뜨며, 확인해보면 apiEncryption.jks 이름으로 잘 생성된 것을 확인할 수 있습니다.

3. 만들어진 key pair의 정보를 좀 더 상세히 살펴보기

아래의 명령어 입력 시, key store password를 입력하라고 나오는데, 좀 전에 key pair 생성하면서 지정했던 키 비밀번호 test1234를 입력합니다.
-v 옵션을 빼면 간략하게 요약된 정보만 출력됩니다.

keytool -list -keystore apiEncryption.jks -v

하이라이트 된 부분을 보시면 PrivateKeyEntry라고 되어 있습니다. private key라고 보시면 됩니다.
암호화/복호화할 때 사용할 수 있습니다.

사실 private key를 만들었고, 이걸가지고 사용할 것이므로 작업은 바로 진행해도 됩니다.
그러나 저는 public key를 만드는 것을 보여드리고자 옵션(4~5)을 추가로 작성했습니다. 따라서 4, 5번은 옵션 입니다.

(옵션)4. 만들어진 이 private key로부터 이번엔 공개키(public key)를 꺼내보기

꺼내보는 것이기 때문에 -export라는 옵션을 사용합니다. 이번에도 keytool로 export 하겠습니다.

참고: -rfc: export할 출력양식을 지정합니다. rfc는 refqust for comment의 약자로, 인터넷에서 사용할 수 있는 표준 공개 양식입니다.
# keytool -export -alias {별칭} -keystore {키스토어 이름} -rfc -file {출력하고자 하는 인증서 파일명}
keytool -export -alias apiEncryptionKey -keystore apiEncryption.jks -rfc -file trustServer.cer

위 명령어 입력 후 다시 파일 목록 확인해보면, 지정한 파일명으로 public key가 생성된 것을 확인가능합니다. 결론적으로 trustServer.cer는 인증서 파일이 됩니다.

(옵션)5. 생성된 trustServcer.cer 인증서 파일을 다시 .jks 파일로 읽어들여 생성해보기

아래 명령어로 publicKey.jks를 생성합니다.

# keytool -import -alias {별칭} -file {읽을 파일명} -keystore {출력할 파일명}
keytool -import -alias trustServer -file trustServer.cer -keystore publicKey.jks

이게 public key로 생성이 되었는지 아까 만들어둔 private key와 비교해보겠습니다.
이번에 만들어진 publicKey.jks와 apiEncryptionKey.jks를 각 상세정보를 출력해보니, publicKey.jks는 trustecCertEntry가 나옵니다. 공개키로 생성되었다는 것을 알 수 있습니다.

6. spring-cloud-starter-starter-bootstrap 라이브러리 추가

이제 프로젝트에서 암호화 적용을 할 것이라서 해당 라이브러리를 추가합니다.

implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'

7. bootstrap.yml 생성 후, 사용할 private key 정보 입력

위에서 키 만들때의 정보를 가지고 아래처럼 알맞게 정보를 넣어줍니다.

encrypt:
  key-store:
    location: file://${user.home}/{키가 있는 경로 입력}/apiEncryption.jks
    password: test1234
    alias: apiEncryptionKey

8. 암호화/복호화 잘 되는지 Postman으로 테스트

암호화: postman으로 암호화 시킬 문자열 1234를 Body의 raw(텍스트형식)으로 지정후 POST 방식으로 encrypt 요청을 합니다.

복호화: 암호화 하여 나온 값을 그대로 Body에 넣어 POST 방식으로 decrypt 요청하니 1234가 잘 나옵니다.

이제 yml 파일의 중요한 설정 값들을 이런 식으로 암호화하여 사용할 수 있습니다.
주의할 점은 yml파일에 넣을 때는 '{cipher}암호화된값' 형식으로 넣어야 암호화된 값으로 인식가능합니다.

예)

spring:
  datasource:
    url: jdbc:h2:tcp://localhost/~/test
    username: sa
    password: '{cipher}AYCEYT3MFiVwZM+m4USiZalskejalfkj' # 암호화된 값이 너무 길어 일부만 넣었습니다. 
    driver-class-name: org.h2.Driver
profile
게을러지고 싶어 부지런한 개발자

0개의 댓글