키 관리
고친 사람 github-actions[bot]
키 관리는 암호에 쓰는 키가 새지 않도록 처음부터 끝까지 돌보는 일입니다. 암호가 아무리 튼튼해도 키를 손에 넣은 사람 앞에서는 소용이 없습니다. 그래서 키를 만드는 순간부터 버리는 순간까지 누가 어떻게 쓰는지를 챙깁니다.
쉽고 빠른 이해
키 관리는 암호 키를 안전하게 다루는 일 전부를 말합니다. 데이터베이스를 암호화했다면 그 암호를 푸는 키를 어디에 둘지부터가 키 관리입니다.
암호 방식은 대개 누구나 아는 공개된 방식입니다. 비밀은 키 하나에만 있습니다. 키가 소스 코드나 설정 파일에 들어 있으면 암호화를 안 한 것과 거의 같습니다.
키 관리는 이렇게 돕니다.
- 짐작할 수 없는 난수로 키를 만든다
- 키를 전용 장비나 서비스에 맡기고 쓸 수 있는 프로그램을 정해 둔다
- 정해 둔 때마다 새 키로 바꾸고 다 쓴 키는 지운다
대가는 운영 부담입니다. 옛 키를 너무 일찍 지우면 그 키로 잠근 데이터를 영영 못 엽니다. 키를 맡긴 서비스가 멈추면 암호를 풀어야 하는 기능도 같이 멈춥니다.
상세
아파트 관리실은 세대마다 열쇠를 만들어 줍니다. 어느 세대에 열쇠 몇 개를 줬는지는 장부에 적어 둡니다. 세입자가 바뀌면 자물쇠를 새로 답니다.
관리실이 열쇠에 하는 일을 암호 키에 하는 것이 키 관리(key management)입니다. 키가 만들어질 때부터 지워질 때까지 그 키를 다루는 일 전부를 말합니다. 암호화로 고객 정보를 잠갔다고 해 봅시다. 그 키를 어디에 두고 어느 서버가 꺼내 쓸 수 있게 할지 정하는 일이 곧 키 관리입니다.
이 항목에서 말하는 키는 데이터베이스의 기본 키나 캐시 키와 다릅니다. 암호 계산에 넣는 비밀 값을 말합니다.
암호 키
암호화에서 지켜야 할 비밀은 키 하나에 몰립니다. 그 까닭을 키가 하는 일에서 찾아봅니다.
암호화는 데이터를 키 없이는 못 읽는 모양으로 바꾸는 일입니다. 그렇게 바뀐 결과를 암호문이라고 부릅니다.
암호 키는 이 계산에 데이터와 함께 넣는 비밀 값입니다. 같은 계산 방법이라도 키가 다르면 전혀 다른 암호문이 나옵니다. 키는 보통 짧은 난수 바이트열입니다.
암호 계산 방법 자체는 대개 공개되어 있습니다. 누구나 설계를 읽고 약점을 찾아볼 수 있어야 믿을 수 있기 때문입니다. 그러니 공격자도 계산 방법은 압니다. 공격자가 모르는 것은 키 하나뿐입니다.
뒤집어 말하면 키가 새는 순간 암호는 아무것도 지켜 주지 못합니다. 암호화가 지키는 힘은 키를 얼마나 잘 지키느냐로 정해집니다.
대칭 키와 공개 키
키는 쓰는 방식에 따라 크게 두 종류로 나뉩니다. 두 종류는 키 관리에서 어려운 곳이 다릅니다.
대칭 키 암호는 잠글 때와 풀 때 같은 키를 쓰는 방식입니다. 계산이 빠르므로 큰 데이터를 암호화할 때 씁니다.
공개 키 암호는 키 두 개를 한 쌍으로 만들어 씁니다. 하나는 누구에게나 알리는 공개 키입니다. 다른 하나는 주인 혼자 쥐는 개인 키입니다.
두 방식에서 키 관리가 어려운 곳을 견주면 이렇습니다.
| 종류 | 끝까지 숨길 키 | 키 관리에서 어려운 점 |
|---|---|---|
| 대칭 키 | 그 키 하나 | 주고받는 양쪽이 같은 키를 남몰래 나눠 가져야 한다 |
| 공개 키 | 개인 키 | 공개 키가 정말 그 주인의 것인지 보증해야 한다 |
공개 키 쪽이 어려운 까닭은 바꿔치기입니다. 누군가 자기 공개 키를 주인의 것인 양 내밀면 보내는 쪽은 그 키로 비밀을 잠가 엉뚱한 사람에게 보내게 됩니다. 그래서 공개 키가 누구의 것인지 보증해 주는 문서인 인증서를 함께 씁니다.
어느 쪽이든 끝까지 숨겨야 하는 키가 있습니다. 키 관리는 그 키를 지키는 일입니다.
키가 새는 경로
암호화를 해 두고도 키 때문에 데이터가 새는 일이 많습니다. 키는 주로 세 경로로 샙니다.
첫째는 키를 소스 코드나 설정 파일에 적어 두는 것입니다. 코드가 저장소에 올라가면 저장소를 읽을 수 있는 사람 모두가 키를 가집니다. 저장소 기록에 한 번 들어간 키는 파일을 고쳐도 옛 커밋에 남습니다.
둘째는 암호문과 키를 같은 서버에 두는 것입니다. 데이터베이스를 암호화하고 키를 같은 서버 디스크에 두면 서버를 뚫은 공격자는 둘을 함께 가져갑니다.
셋째는 한 키를 오래 쓰는 것입니다. 키가 샌 줄 모르는 동안 공격자는 그 키로 잠근 모든 데이터를 엽니다. 한 키를 오래 쓸수록 그 키 하나에 걸린 데이터가 늘어납니다.
키 관리는 이 세 경로를 하나씩 막습니다. 키를 코드 밖의 전용 보관소에 둡니다. 암호문과는 떨어뜨려 둡니다. 정해 둔 때마다 바꿉니다.
키 생명 주기
키는 만들어진 뒤 여러 상태를 거쳐 지워집니다. 이 흐름을 키 생명 주기라고 부릅니다. 아래 그림은 키 하나가 거치는 상태와 상태가 바뀌는 계기를 보입니다.
stateDiagram-v2
state "생성" as gen
state "사용 중" as active
state "풀기 전용" as decrypt
state "유출 의심" as leaked
state "파기" as destroyed
[*] --> gen
gen --> active: 배포
active --> decrypt: 회전
active --> leaked: 샌 흔적 발견
decrypt --> destroyed: 옛 데이터를 새 키로 옮김
leaked --> destroyed
destroyed --> [*]
그림의 상태마다 하는 일과 그 까닭을 차례로 봅니다.
키는 암호학적으로 안전한 난수 생성기로 생성합니다. 보통의 난수 함수는 앞의 값을 보고 다음 값을 짐작할 수 있습니다. 짐작할 수 있는 키는 공격자가 후보를 차례로 넣어 보면 맞힙니다.
배포는 만든 키를 쓸 프로그램에 건네는 단계입니다. 키는 그 키를 쓸 서버만 받아야 합니다. 전달 도중에 새어서도 안 됩니다. 대칭 키는 양쪽이 같은 키를 가져야 하므로 이 단계가 특히 어렵습니다.
그래서 대칭 키를 나눌 때는 키 교환을 씁니다. 키 교환은 남이 엿볼 수 있는 통신망 위에서 두 쪽이 같은 비밀 키를 나눠 갖는 절차입니다. 공개 키 암호를 써서 키가 통신망에 드러나지 않게 합니다.
사용 중인 키로는 데이터를 잠그고 풉니다. 이 상태에서는 누가 언제 키를 썼는지 감사 로그에 남깁니다. 감사 로그는 누가 무엇을 했는지 나중에 고칠 수 없게 남긴 기록입니다. 기록이 있어야 키가 샜을 때 어디서 샜는지 거슬러 찾습니다.
키의 용도는 암호화만이 아닙니다. 서명은 키로 데이터에 도장을 찍어 누가 만들었는지 증명하는 일입니다.
한 키는 한 용도에만 씁니다. 암호화에 쓰는 키로 서명까지 하면 한쪽 쓰임새의 약점이 다른 쪽으로 번질 수 있습니다. 용도를 나눠 두면 한 키가 새도 피해가 그 용도에서 그칩니다.
키 회전은 쓰던 키를 새 키로 바꾸는 일입니다. 샌 줄 모르는 키가 있어도 바꾼 뒤로는 공격자가 새 데이터를 못 엽니다. 한 키에 걸리는 데이터의 양도 줄어듭니다.
회전한 옛 키는 바로 지우지 않고 풀기 전용으로 둡니다. 옛 키로 잠근 데이터가 아직 남아 있기 때문입니다. 새로 잠글 때는 새 키만 씁니다. 옛 키는 옛 데이터를 열 때만 꺼냅니다.
그러려면 암호문마다 어느 키로 잠갔는지 적어 둬야 합니다. 보통 키마다 버전 번호를 붙입니다. 그 번호를 암호문 옆에 함께 저장합니다. 옛 데이터를 새 키로 전부 다시 잠그고 나면 옛 키를 파기할 수 있습니다.
키가 샌 흔적이 보이면 그 키는 유출 의심 상태가 됩니다. 이때는 정해 둔 회전 때를 기다리지 않습니다. 먼저 새 키를 만들어 데이터를 서둘러 옮깁니다. 옮기고 나면 샌 키를 파기합니다.
개인 키가 샜다면 짝이 되는 공개 키도 더는 믿으면 안 됩니다. 그래서 그 공개 키를 보증하던 인증서를 무효로 돌리고 널리 알립니다. 이 절차가 인증서 폐기입니다.
파기는 키를 되살릴 수 없게 지우는 일입니다. 키를 파기하면 그 키로 잠근 데이터는 누구도 못 엽니다.
이 성질을 거꾸로 써서 데이터를 지우는 방법이 암호학적 삭제입니다. 백업 곳곳에 흩어진 복사본을 전부 찾아 지우는 대신 그 데이터를 잠근 키 하나만 파기합니다. 복사본이 남아 있어도 암호문이라 아무도 읽지 못합니다.
키를 감싸는 키
키를 지키려고 키를 암호화하면 그 키를 잠근 키를 또 지켜야 합니다. 이 되풀이는 두 층에서 끊습니다.
키를 다른 키로 암호화하는 것을 키를 감싼다(key wrapping)고 말합니다. 감싼 키는 도둑맞아도 바깥 키가 없으면 쓸 수 없습니다.
실무에서는 두 층으로 나눕니다. 데이터를 잠그는 키를 데이터 키, 데이터 키를 감싸는 키를 마스터 키라고 부릅니다. 데이터 키는 감싼 채로 암호문 옆에 저장합니다. 마스터 키는 전용 장비나 서비스 밖으로 나오지 않게 둡니다.
flowchart TD
M["마스터 키 · 전용 장비 안에만 있다"]
M -->|감싼다| D1["데이터 키 1 · 감싼 채 저장"]
M -->|감싼다| D2["데이터 키 2 · 감싼 채 저장"]
D1 -->|잠근다| R1["고객 정보"]
D2 -->|잠근다| R2["주문 기록"]
그림처럼 마스터 키 하나가 데이터 키 여럿을 감쌉니다. 데이터 키는 저마다 맡은 데이터를 잠급니다. 이렇게 두 층으로 나눈 방식을 봉투 암호화라고 부릅니다.
두 층으로 나누는 까닭의 하나는 속도입니다. 큰 데이터를 매번 전용 장비로 보낼 필요가 없습니다. 장비에는 짧은 데이터 키만 보내 풀게 합니다. 큰 데이터는 애플리케이션 서버가 그 데이터 키로 직접 풉니다.
다른 까닭은 회전입니다. 마스터 키를 바꿀 때 데이터 키만 새 마스터 키로 다시 감싸면 됩니다. 데이터 자체를 전부 다시 암호화하지 않아도 됩니다.
키를 맡는 장비와 서비스
마스터 키처럼 끝까지 지켜야 하는 키는 일반 서버 디스크에 두지 않습니다. 키를 지키는 일만 하는 장비나 서비스에 맡깁니다.
하드웨어 보안 모듈(HSM, Hardware Security Module)은 키를 보관하고 암호 계산을 대신 해 주는 전용 장비입니다. 키는 장비 안에서 만들어집니다. 만들어진 키는 장비 밖으로 나오지 않습니다. 서버는 데이터를 장비에 보내 잠가 달라거나 풀어 달라고 요청만 합니다.
HSM 은 장비를 뜯어 키를 꺼내려 하면 키를 스스로 지우도록 만듭니다. 서버 한 대를 훔쳐 가도 키는 따라가지 않습니다.
키 관리 서비스(KMS, Key Management Service)는 키 보관과 암호 계산을 네트워크 너머에서 맡아 주는 서비스입니다. 클라우드 업체들이 이런 서비스를 내놓고 있습니다. 애플리케이션은 네트워크 요청으로 데이터 키를 감싸 달라거나 풀어 달라고 부탁합니다.
KMS 를 쓰면 누가 어느 키를 쓸 수 있는지를 서비스의 접근 제어 설정으로 정합니다. 접근 제어는 누가 무엇에 손댈 수 있는지를 정하고 지키게 하는 장치입니다. 키를 꺼낼 수 있는 서버를 좁혀 두면 다른 서버가 뚫려도 키는 안전합니다.
키를 어디까지 챙기나
암호를 쓰는 곳이면 어디든 키 관리가 따라옵니다. 달라지는 것은 키를 두는 곳과 그 비용입니다. 아래 표는 키가 지키는 것에 따라 고르는 보관 방식입니다.
| 키가 지키는 것 | 보관 방식 |
|---|---|
| 개발용 테스트 데이터 | 개발자 컴퓨터의 로컬 설정 파일 |
| 서비스의 운영 데이터 | 키 관리 서비스와 봉투 암호화 |
| 서명 키처럼 새면 되돌리기 어려운 키 | 하드웨어 보안 모듈. 여러 사람이 함께 승인해야 쓸 수 있게 한다 |
새었을 때 되돌리기 어려운 키일수록 표의 아래쪽을 고릅니다. 아래로 갈수록 비용과 호출 지연이 늘어납니다.
시크릿 관리와 코드 서명
키 관리와 자주 함께 나오는 말이 둘 있습니다. 하나는 키 관리를 품는 더 넓은 일입니다. 다른 하나는 키 관리에 기대는 일입니다.
시크릿 관리는 비밀번호, 접속 토큰, 암호 키처럼 남이 알면 안 되는 값을 코드 밖에 두고 다루는 일입니다. 키 관리는 그중 암호 키를 다루는 부분입니다. 암호 키에는 다른 비밀에 없는 사정이 있습니다. 옛 키를 지우면 그 키로 잠근 데이터를 못 엽니다.
코드 서명은 배포하는 프로그램에 개인 키로 서명해 만든 사람을 증명하는 일입니다. 사용자의 컴퓨터는 공개 키로 서명을 확인한 뒤에야 프로그램을 믿습니다.
서명용 개인 키가 새면 공격자가 악성 프로그램에 진짜 서명을 붙일 수 있습니다. 그래서 서명 키는 하드웨어 보안 모듈 안에 두는 경우가 많습니다.
키를 잃는 위험과 운영 부담
키 관리에는 값이 따릅니다. 키를 단단히 지킬수록 잃을 위험과 운영 부담이 함께 커집니다.
가장 큰 위험은 키를 잃는 것입니다. 키를 지우거나 잃어버리면 그 키로 잠근 데이터는 주인도 못 엽니다. 사본을 여러 벌 두면 잃을 걱정은 줄지만 샐 곳이 늘어납니다. 키를 숨기는 일과 키를 잃지 않는 일이 서로 반대로 당깁니다.
키를 맡긴 서비스가 멈추면 암호를 푸는 기능도 멈춥니다. 데이터를 읽을 때마다 키 관리 서비스를 부르는 구조라면 그 서비스의 장애가 곧 우리 서비스의 장애가 됩니다. 풀어 둔 데이터 키를 잠시 메모리에 두고 다시 쓰면 호출 수가 줄어듭니다.
회전에도 일이 따릅니다. 옛 키를 풀기 전용으로 얼마나 남길지, 옛 데이터를 언제 새 키로 옮길지를 정해야 합니다. 사람이 손으로 하면 빠뜨리기 쉬워서 대개 자동화합니다.
관련 항목
키 관리가 다루는 키의 종류
암호화 키 · 대칭 키 암호 · 공개 키 · 개인 키 · 키 쌍 · 세션 키 · 마스터 키 · 데이터 키
키 생명 주기를 이루는 단계
키 생명 주기 · 키 생성 · 키 교환 · 키 유도 함수 · 키 회전 · 인증서 폐기 · 키 파기 · 암호학적 삭제
키를 감싸고 나누는 방식
봉투 암호화 · 키 래핑 · 키 계층 · 비밀 분산
키를 맡아 지키는 장비와 서비스
하드웨어 보안 모듈 · 키 관리 서비스 · 신뢰 플랫폼 모듈 · 시크릿 저장소 · 키 저장소
키 관리에 기대는 보안 기능
암호화 · 전자 서명 · 코드 서명 · TLS · 인증서 · 공개 키 기반 구조 · 인증 기관
키에 손대는 사람을 묶는 통제
키 관리를 떠받치는 암호 원리
케르크호프스 원리 · 난수 생성기 · 공개 키 암호 · 암호학
키가 새는 경로
하드코딩된 비밀 · 자격 증명 유출 · 사이드 채널 공격 · 공급망 공격
키 관리가 속하는 상위 분류
다른 이름: key management · 암호 키 관리 · 키 매니지먼트 · cryptographic key management