해당 포스팅은 인프런의
Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
을 수강하면서 정리하는 글입니다. 이도원님의 Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
안녕하세요 오늘은 [Spring Cloud] Spring Cloud Config 에 대해 에 이어 두번째 시간으로 구성한 설정 파일의 보안적인 측면을 고려해 보안을 강화해보겠습니다.
[ 살펴볼 기술 ]
1. Spring Cloud Config
2. JDK Keytool
3. JKS(Java Key Store)
4. SSL
지난 포스팅 까지 우리는 설정 파일 저장소(Git 원격 레포지토리) 을 만들고 Config Server
을 구축해서 설정 파일을 읽어오고 users-service 라는 Config Client
도 직접 구동시켜서 읽어온 설정 파일 결과도 확인해보았습니다.
설정 파일 저장소 역할을 하는 원격 Git 레포지토리로 돌아가보겠습니다.
이미지에서 볼 수 있듯이, 민감한 보안 정보가 포함된 설정 정보가 그대로 노출되고 있습니다.
그렇다면 이미지에 있는 레포지토리를 Private 으로 변경하면 보안 위협을 제거할 수 있지 않을까요?
물론 해당 레포지토리를 Private 으로 변경하면 외부에 노출되지 않겠지만, 여전히 보안 위협이 사라지지 않습니다 🙅♂️
이렇게 단지 숨기는 방식의 보안
은 전혀 안전하지 않습니다.
개발자는 설정 파일 정보 레포지토리를 Private 로 변경함으로서, 보안 처리를 했다는 생각 때문에 안심할 수 있는데, 오히려 보안을 하지 않는 것 보다 못할 수 있습니다.
또한 설정 파일 저장소의 데이터가 Config Server
로 네트워크를 통해 전송될때 Plain Text
형태로 전송되기 때문에 중요한 정보를 탈취당할 수 있습니다.
[기존 Config Server 의 문제점]
여기서 우리는 데이터 암호화 기술의 필요성을 인지할 수 있습니다 🤔
그렇다면 Spring Cloud Config
기술과 데이터 암호화 기술이 어떻게(HOW) 함께 동작할까요? 간단한 동작 원리를 살펴보겠습니다 ❗️
암호화된 설정 정보를 사용하기 위해서는 암호화 키를 사용해 Config Server
구성해야 하며, Config Server
로 부터 설정 정보가 Config Client
에 제공되기 전에 복호화 키를 이용해 복호화 됩니다.
즉, 개발자는 Config Server
가 바라보고 있는 설정 정보 저장소에 있는 데이터를 암호화 해야 하며, Config Server
가 설정 정보 저장소의 암호화된 최신 데이터를 가져온 후, Config Client
에게 제공할때 암호화된 데이터가 복호화되도록 구성해야 합니다.
데이터를 암호화하는 방식에는 대칭키
방식과 비대칭키
방식이 존재합니다.
간단한 실습을 통해 두 방식 ❗️
: [Spring] AES 암호화 알고리즘에 대해
대칭키 방식은 암/복호화에 사용하는 키가 동일한 방식입니다.
해당 방식은 암호화키와 복호화 키가 같기 때문에 상대적으로 간편합니다.
게다가, 대표적인 대칭키 암호화 알고리즘인 AES
는 128 ~ 256 비트의 키를 바로 적용할 수 있어서 보안성이 뛰어남과 동시에 공개된 알고리즘이라 누구나 사용할 수 있습니다.
// Config Server 의 bootstrap.yml
encrypt:
key: abcdefghijklmnopqrstuvwxyz0123456789
해당 정보는 암호화와 복호화에 사용되는 대칭키입니다.
Config Server 을 재가동하고 암호화 앤드포인트를 호출합니다.
POST http://[Config Server 주소]:[Config Server 포트]/encrypt
이미지에서 볼 수 있듯이, Config Server
가 bootstrap.yml 가지고 있는 대칭키로 암호화가 된 것을 확인할 수 있습니다.
Config Server
는 복호화 관련 앤드포인트도 제공합니다 ❗️
POST http://[Config Server 주소]:[Config Server 포트]/decrypt
정상적으로 복호화된 것을 확인할 수 있습니다.
대칭키 암호화 방식은 앞에서 살펴보았듯이, 암호화 키와 복호화 키가 동일합니다.
게다가 널리 쓰이는 대표적인 대칭키 암호화 알고리즘인 AES
는 128 ~ 256 비트의 키를 적용할 수 있어서 보안성이 뛰어남과 동시에 누구에게나 공개된 알고리즘이라 누구나 사용가능합니다.
하지만, 여기에는 치명적인 단점이 존재합니다 ❗️
만약 Config Server의 bootstrap.yml 에 있는 대칭키가 노출되면 어떻게 될까요?
정답은 암호화를 하지 않는 것과 같으므로 보완성 측면에서 효과가 없습니다.
따라서 암/복호화 키가 동일한 대칭키 암호화를 사용할 때는 대칭키 관리에 각별한 주의가 필요합니다 👨💻
비대칭키 방식은 암/복호화에 사용하는 키가 다른 방식입니다.
일반적으로 암호화할 때 Private Key 가 사용되며, 복호화할 때 Public Key 가 사용됩니다.
여기서는 Java 의 JDK Keytool
을 사용해보겠습니다.
Java는 JCE(Java Cryptography Extenstion)
을 통해 암호 관련 기능을 제공합니다.
즉, JCE 는 Java 에서 암호화와 관련된 다양한 기능을 제공하는 확장 패키지입니다.
Java 11 이상 부터는 기본적으로 제공하고 있으며 하위 버전에서는 관련 라이브러리를 직접 다운받아야 사용 가능합니다.
JKS(Java Key Store)
이란 JCE 을 이용해 만든 키를 저장하고 관리하는 저장소입니다.
마찬가지로 Java 에서 제공하는 키 저장소이며, Config Server
에서는 설정 파일을 암/복호화 하기 위해 JCE
와 JKS
을 이용해 사용할 수 있습니다.
JCE : Java 에서 제공하는 비대칭키를 생성하는 기능을 제공하는 암호 관련 라이브러리
JKS : Java 에서 제공하는 JCE 에서 만든 비대칭키를 저장하고 관리하는 저장소
JDK Keytool 이란
키와 인증서를 관리하는 Util 로서, Private Key, Public Key 및 자신이 권한을 부여한 인증서를 관리할 수 있게하며, 자료의 보장과 전자서명에 의한 인증을 관리할 수 있게 합니다. 여기서 생성된 Key 와 인증서는 JKS(Java Key Store) 라는 곳에 저장을 하게 되며, 파일로 구현이됩니다.
: Spring Cloud Config - 비대칭키로 properties 암호화하기
JDK Keytool
은 앞서 살펴본 JCE 에 속하는 도구입니다.
해당 Util 과 JKS을 통해 비대칭키를 포함하는 Key Store 파일을 생성하여 설정 정보의 암호화를 진행해보겠습니다.
Keytool
의 명령어를 통해 Spring Cloud Config Server
에서 사용할 key 파일을 생성합니다.
$ keytool -genkeypair -alias ecommerceEncryptionKey -keyalg RSA \\
-dname -"CN=Dong Choi, OU=API Development, O=ChoiDongkuen.co.kr, L=KR" -keypass \\
"test1234" -keystore ecommerceEncryptionKey.jks -storepass "test1234"
-genkeypair : 키쌍(개인키 & 공개키) 을 생성하는 옵션
-alias ecommerceEncrpytionKey : 생성되는 키 쌍에 대한 별칭을 지정 해당 별칭은 Key Store 에서 키 쌍 식별자로 사용(원하는 이름으로 생성하면 됩니다.)
-keyalg RSA : RSA 알고리즘을 사용하여 키 쌍을 생성(RSA 알고리즘은 대표적인 비대칭키 방식의 알고리즘입니다.)
-dname : "CN=Dong Choi, OU=API Development, O=ChoiDongkuen.co.kr, L=KR" :
인증서에 포함될 사용자의 이름, 조직, 지역 및 국가 정보를 지정
-keypass "test1234" : 개인키에 대한 암호를 지정
-keystore ecommerceEncryptionKey.jks : 생성될 키 쌍을 저장할 키 Key Store 파일의 경로와 이름을 지정
-storepass "test1234" : Key Store 파일에 대한 암호를 지정
입력한 비밀번호를 이용해 암호키가 생성되며, 생성된 암호키를 Key Store
파일에 저장합니다.
이때 파일 확장자는 .jks
입니다.
$ keytool -list -keystore ecommerceEncryptionKey.jks -v
해당 명령어와 설정한 비밀번호를 통해 생성한 Key Store 파일의 정보를 확인할 수 있습니다.
해당 이미지는 앞에서 살펴본 명령어들을 실행한 결과입니다.
이 파일은 공개키 및 개인키를 포함하고 있으며, 이후에 암호화 및 복호화 작업에 사용될 수 있습니다.
앞에서 생성한 Key Store 파일은 서버에서 사용되며, 클라이언트에게 제공해야할 공개키를 가지는 파일을 제공해야 합니다.
일반적으로 공개키는 암호화, 개인키는 복호화를 위해 사용됩니다.
즉, 여기서 말하는 인증서는 생성한 공개키를 제공하는 방법 중 하나입니다.
간단하게 인증서를 통해 공개키를 포함하는 인증된
클라이언트 전용 Key Store 파일을 생성한다고 이해하면 됩니다 🤨
이를 위해 먼저 생성된 Key Store 파일을 이용해 공개키를 위한 인증서를 만들어보겠습니다 ❗️
$ keytool -export -alias ecommerceEncryptionKey -keystore ecommerceEncryptionKey.jks -rfc -file trust_ecommerceKey.cer
// $ keytool -export -alias [별칭] -keystore [위에서 만들어진 파일명].jks -rfc -file [인증서명].cer
의도한 대로 ecommerceEncryptionKey.jks
로 부터 trust_ecommercetKey.cer
인증서가 생성된 것을 확인할 수 있습니다 ❗️
다음으로 앞에서 만든 인증서를 통해 인증된 Key Store 파일
을 만들어보겠습니다.
$ keytool -import -alias trust_ecommerceKey -file truest_ecommerceKey.cer -keystore publicKey.jks
// $ keytool -import -alias [별칭] -file [인증서 파일].cer -keystore [새로 만들 파일].jks
인증서를 통해 클라이언트에게 전달할 새로운 Key Store 파일을 만듭니다.
해당 이미지를 통해 두개의 Key Store 파일과 하나의 인증서 파일이 만들어진 것을 확인할 수 있습니다 ❗️
지금까지 두개의 Key Store 파일을 생성했습니다. 둘다 같은 Key Store 파일인데 무엇이 다른걸까요? 🤔
이번 단계에서는 둘의 차이점을 알아보겠습니다.
ecommerceEncryptionKey.jks
처음 생성한 ecommerceEncryptionKey.jks
는 비대칭 키 쌍을 생성하고, 개인키와 공개키를 포함하는 Key Store 파일입니다. 주로 서버에서 가지고 있으며 여기서는 Config Server
가 가집니다 👨💻
publicKey.jks
인증서를 통해 생성한 publicKey.jks
는 공개키만 가지는 Key Store 파일입니다.
주로 공개 키를 다른 서비스나 클라이언트에게 제공하는 용도로 사용됩니다.
인증서를 통해 생성된 Key Store 파일이기 때문에 인증의 의미로 trustedCertEntry
라고 표기가 되는것을 확인할 수 있습니다.
이제 모든 준비가 끝났습니다.
생성한 Key Store 파일의 경로와 이름을 통해 Config Server 에 등록만 해주면 비대칭키 기법 적용
이 모두 끝납니다.
[Spring Cloud] Spring Cloud Config 에 대해 에서 구축한 Config Server 에 적용해보겠습니다.
[1] 먼저 Key Store 파일이 존재하는 경로를 확인합니다.
여기서 /Users/Dongkuen
(맥OS 기준) 은 저의 home 경로입니다.
[2] 정보에 맞게 Config Server 의 bootstrap.yml 을 작성해줍니다.
encrypt:
key-store:
location: file://${user.home}/Desktop/Github/ecommerceDiscoveryService/keystore/ecommerceEncryptionKey.jks
password: test1234
alias: ecommerceEncryptionKey
location
속성에는 개인키와 공개키를 모두 가지는 Key Store 파일의 경로를 설정합니다.(ecommerceEncryptionKey.jks
)
password
속성에는 Key Store 파일을 생성할 때 지정했던 비밀번호를 입력해주며, alias
에서 Key Store 파일을 생성할 때 지정했던 별칭을 입력합니다.
[3] Config Server 재가동 및 암호화 앤드포인트 호출
Config Server 을 재가동하고 대칭키 방식과 동일하게 Config Server
의 암호화 앤드포인트를 호출합니다.
저는 Config Server 의 클라이언트인 users-service
의 데이터베이스 비밀번호를 암호화 하겠습니다.
이미지처럼 암호화 앤드포인트 호출 시 암호화되길 원하는 정보을 암호화할 수 있습니다.
앞에서 살펴보았던 대칭키 암호화보다 더 길고 복잡하게 암호화 되는 것을 확인할 수 있습니다.
이렇게 암호화된 정보를 설정 파일 저장소
에 저장하면 Config Server
에서 가져올 때 가지고 있는 개인키로 복호화합니다 ❗️
이후 애플리케이션 즉, 클라이언트에게 복호화된 설정 정보를 제공합니다.
위에서 암호화한 데이터베이스 비밀번호 설정 정보를 복호화 해보겠습니다.
마찬가지로, 대칭키에서 살펴보았던것과 동일하게 Config Server
의 복호화 앤드포인트를 호출합니다.
정상적으로 복호화되는 것을 확인할 수 있습니다 ❗️
[4] 설정 파일 저장소에 적용
마지막으로 이렇게 암호화된 데이터베이스 비밀번호 설정값을 설정 파일 저장소에 저장하겠습니다.
대칭 암호화 기법과 마찬가지로 {cipher}암호화된 설정 값
형식으로 저장합니다.
Config Server
가 설정 파일 저장소
로부터 암호화된 설정 정보를 잘 가지고 오는지 확인해보겠습니다.
Config Server
에서 설정 정보를 가져올때는 복호화된 설정 정보로 가져오는 것을 확인할 수 있습니다 ❗️
이번 포스팅에서는 spring cloud config
기술에서 더 나아가 대칭키와 비대칭키로 암호화 및 복호화 하는 방법에 대해 알아보았습니다.
spring cloud config
기술은 결국 애플리케이션에서 사용하는 민감한 설정 정보를 외부 저장소에서 효율적으로 관리하기 위해 사용되는 기술이고, 여기서 보안적인 측면을 고려하지 않을 수 없습니다.
특히, 분산 시스템을 이루는 애플리케이션에서는 더욱 그러합니다.
따라서 실제 프로젝트나 서비스 개발에서 Config Server 을 구축하게 된다면 꼭 적용해보아야할 기술들이라고 생각합니다 ❗️
Spring Cloud Config의 설정 파일 비대칭키로 암/복호화
[Spring] Spring Cloud Config 도입하기 및 private 레포지토리 SSL로 연결 설정 및 privateKey 암호화
[Spring Cloud 비대칭키로 암호화하기]
Spring Cloud Config 에서 대칭키를 이용한 application.yml 의 민감 정보 암호화 하기