Transit 시크릿 엔진
Transit 시크릿 엔진
Transit 시크릿 엔진은 전송 중(in-transit) 데이터에 대한 암호 함수를 처리해요. Vault는 시크릿 엔진으로 보내진 데이터를 저장하지 않아요. 이를 "cryptography as a service" 또는 "encryption as a service"로 볼 수도 있어요. Transit 시크릿 엔진은 데이터에 서명·검증하고, 데이터의 해시와 HMAC을 생성하며, 무작위 바이트의 소스로도 작동할 수 있어요.
transit의 주요 사용 사례는 애플리케이션의 데이터를 암호화하면서도 그 암호화된 데이터를 어떤 기본 데이터 저장소에 저장하는 것이에요. 이렇게 하면 적절한 암호화/복호화의 부담을 애플리케이션 개발자에게서 뺏어 Vault 운영자에게 넘겨요.
키 파생(key derivation)이 지원되어, 사용자가 제공한 컨텍스트 값에 기반해 새 키를 파생함으로써 같은 키를 여러 용도로 사용할 수 있어요. 이 모드에서는 같은 입력 값이 같은 암호문을 생성하는 수렴 암호화(convergent encryption)를 선택적으로 지원할 수 있어요.
데이터 키(datakey) 생성은 프로세스가 지정된 비트 길이의 고엔트로피 키를 요청하고, 이름 있는 키로 암호화되어 반환되게 해요. 보통은 즉시 사용할 수 있도록 키를 plaintext로도 반환하지만, 감사 요구 사항을 수용하기 위해 비활성화할 수 있어요. 지원되는 SDK와 Vault CLI 같은 워크플로뿐 아니라 여러분의 소프트웨어도 데이터 키 집합 생성을 사용해 엔벨로프 암호화에 사용할 키를 생성할 수 있어요.
출처: 문서
본문
작업 집합 관리 (Working set management)
Transit 엔진은 키 버전 관리를 지원해요. 키의 지정된 min_decryption_version보다 이전인 키 버전은 아카이브되고 나머지 키 버전은 작업 집합(working set)에 속해요. 이는 키 로딩을 빠르게 유지하기 위한 성능 고려 사항이자 보안 고려 사항이에요. 이전 버전의 키로 복호화를 허용하지 않음으로써, 구식(하지만 민감한) 데이터에 대응하는 발견된 암호문을 대부분의 사용자가 복호화할 수 없지만, 긴급 상황에서는 min_decryption_version을 되돌려 정당한 복호화를 허용할 수 있어요.
현재 이 아카이브는 단일 스토리지 항목에 저장돼요. HA 기능에 Raft나 Paxos를 사용하는 일부 스토리지 백엔드에서는 빈번한 회전으로 아카이브의 스토리지 항목 크기가 스토리지 백엔드가 처리할 수 있는 것보다 커질 수 있어요. 빈번한 회전이 필요하다면 시간 범위에 대응하는 이름 있는 키(예: 5분 구간을 가장 가까운 5의 배수로 내린 것)를 사용하면 좋은 대안이 될 수 있어, 한 번에 여러 키를 활성화하고 주어진 시점에 어떤 키를 사용할지 결정하는 결정적 방법을 제공해요.
NIST 회전 지침
손상이 없더라도 암호화 키의 주기적 회전을 권장해요. AES-GCM 키의 경우 NIST 간행물 800-38D 지침에 따라 키 버전이 약 2^32회의 암호화를 수행하기 전에 회전이 발생해야 해요. 운영자는 키의 암호화 속도를 추정하고 이를 사용해 지침 한도에 도달하지 않게 하는 회전 빈도를 결정하는 것을 권장해요. 예를 들어 추정 속도가 하루 4000만 작업이라면 3개월마다 키를 회전하는 것으로 충분해요.
키 유형 (Key types)
현재 transit 시크릿 엔진은 다음 키 유형을 지원해요(모든 키 유형은 별도의 HMAC 키도 생성해요).
aes128-gcm96— 128비트 AES 키와 96비트 nonce를 사용하는 AES-GCM; 암호화, 복호화, 키 파생, 수렴 암호화 지원aes256-gcm96— 256비트 AES 키와 96비트 nonce를 사용하는 AES-GCM; 암호화, 복호화, 키 파생, 수렴 암호화 지원 (기본값)chacha20-poly1305— 256비트 키를 사용하는 ChaCha20-Poly1305; 암호화, 복호화, 키 파생, 수렴 암호화 지원ed25519— Ed25519; 서명, 서명 검증, 키 파생 지원ecdsa-p256— P-256 커브를 사용하는 ECDSA; 서명과 서명 검증 지원ecdsa-p384— P-384 커브를 사용하는 ECDSA; 서명과 서명 검증 지원ecdsa-p521— P-521 커브를 사용하는 ECDSA; 서명과 서명 검증 지원rsa-2048— 2048비트 RSA 키; 암호화, 복호화, 서명, 서명 검증 지원rsa-3072— 3072비트 RSA 키; 암호화, 복호화, 서명, 서명 검증 지원rsa-4096— 4096비트 RSA 키; 암호화, 복호화, 서명, 서명 검증 지원hmac— HMAC; HMAC 생성과 검증 지원managed_key— 관리 키; 백업 키 관리 솔루션에 따라 다양한 작업 지원. 자세한 내용은 관리 키를 참고하세요.aes128-cmac— 128비트 AES 키를 사용하는 CMAC; CMAC 생성과 검증 지원aes192-cmac— 192비트 AES 키를 사용하는 CMAC; CMAC 생성과 검증 지원aes256-cmac— 256비트 AES 키를 사용하는 CMAC; CMAC 생성과 검증 지원ml-dsa— ML-DSA; 서명과 서명 검증 지원hybrid— 두 서명 알고리즘의 조합; 서명과 서명 검증 지원slh-dsa— SLH-DSA (비대칭)aes128-cbc— CBC 모드의 AES-128 (대칭, 파생과 수렴 암호화 지원)aes256-cbc— CBC 모드의 AES-256 (대칭, 파생과 수렴 암호화 지원)
참고: FIPS 140-3 모드에서는 다음 알고리즘은 인증되지 않았으므로 사용해서는 안 돼요:
chacha20-poly1305와ed25519.
참고: 모든 키 유형은 키 생성 시점이나 회전 시 생성된 두 번째 무작위 키를 통해 HMAC 작업을 지원해요. HMAC 키 유형은 HMAC만 지원하며, HMAC 작업에 관해서는 다른 알고리즘과 동일하게 동작하지만 키 가져오기(import)를 지원해요. 기본적으로 HMAC 키 유형은 256비트 키를 사용해요.
RSA 작업은 다음 방법 중 하나를 사용해요.
- OAEP (encrypt, decrypt), SHA-256 해시 함수와 MGF 사용
- PSS (sign, verify), MGF에도 사용되는 설정 가능한 해시 함수 사용
- PKCS#1v1.5: (sign, verify), 설정 가능한 해시 함수 사용
수렴 암호화 (Convergent encryption)
수렴 암호화는 같은 plaintext+context 집합이 항상 같은 암호문을 만들도록 하는 모드예요. 키 파생 함수를 사용해 키를 파생하고 nonce도 결정적으로 파생함으로써 이를 수행해요. 이 속성들이 2^256 크기의 키 공간에 걸친 어떤 plaintext·ciphertext 조합에도 다르기 때문에, nonce 재사용의 위험은 거의 0이에요.
이것은 많은 실용적 용도가 있어요. 흔한 사용 모드는 값이 데이터베이스에 암호화되어 저장되되 제한된 조회/쿼리 지원으로, 특정 필드에 대해 같은 값을 가진 행을 쿼리로 반환할 수 있게 하는 것이에요.
알고리즘의 필요한 업그레이드를 수용하기 위해 역사적으로 수렴 암호화의 여러 버전이 지원됐어요.
- 버전 1은 클라이언트가 자신의 nonce를 제공해야 했어요. 매우 유연하지만 잘못하면 위험할 수 있어요. 이는 Vault 0.6.1에만 있었고, 이 버전을 사용하는 키는 업그레이드할 수 없어요.
- 버전 2는 파라미터를 파생하는 알고리즘 접근 방식을 사용했어요. 그러나 사용된 알고리즘은 오프라인 plaintext 확인 공격에 취약했고, plaintext 크기가 작으면 공격자가 복호화를 무차별 대입할 수 있었어요. 버전 2를 사용하는 키는 새 키 버전으로 rotate 작업을 수행하기만 하면 업그레이드할 수 있어요. 그러면 기존 값은 새 키 버전에 대해 다시 래핑(rewrap)될 수 있고 버전 3 알고리즘을 사용하게 돼요.
- 버전 3은 오프라인 plaintext 확인 공격에 저항하도록 설계된 다른 알고리즘을 사용해요. PRF를 사용해 plaintext에서 nonce를 생성한다는 점에서 AES-SIV와 유사해요.
설정 (Setup)
대부분의 시크릿 엔진은 본래 기능을 수행하기 전에 미리 설정을 해 둬야 해요. 이 단계들은 보통 운영자나 설정 관리 도구가 수행해요.
1. Transit 시크릿 엔진을 활성화합니다.
$ vault secrets enable transit
Success! Enabled the transit secrets engine at: transit/
기본적으로 시크릿 엔진은 엔진 이름과 같은 경로에 마운트돼요. 다른 경로에 활성화하려면 -path 인자를 사용하면 됩니다.
2. 이름 있는 암호화 키를 만듭니다.
$ vault write -f transit/keys/my-key
Success! Data written to: transit/keys/my-key
보통 각 애플리케이션은 자체 암호화 키를 가져요.
사용법 (Usage)
시크릿 엔진이 설정되고 사용자/머신이 적절한 권한을 가진 Vault 토큰을 갖게 되면 이 시크릿 엔진을 사용할 수 있어요.
1. 이름 있는 키로 /encrypt 엔드포인트를 사용해 일부 plaintext 데이터를 암호화합니다.
참고: 모든 plaintext 데이터는 base64로 인코딩되어야 해요. 이 요구 사항의 이유는 Vault가 plaintext가 "텍스트"일 것을 요구하지 않기 때문이에요. PDF나 이미지 같은 바이너리 파일일 수 있어요. JSON 페이로드의 일부로 이 데이터를 안전하게 전송하는 가장 쉬운 방법은 base64 인코딩하는 것이에요.
$ vault write transit/encrypt/my-key plaintext=$(echo "my secret data" | base64)
Key Value
--- -----
ciphertext vault:v1:8SDd3WHDOjf7mq69CyCqYjBXAiQQAVZRkFM13ok481zoCmHnSeDX9vyf7w==
반환된 암호문은 vault:v1:로 시작해요. 첫 번째 접두사(vault)는 Vault가 래핑했음을 식별해요. v1은 키 버전 1이 plaintext를 암호화하는 데 사용됐음을 나타내요. 따라서 키를 회전할 때 Vault는 복호화에 어떤 버전을 사용할지 알아요. 나머지는 초기화 벡터(IV)와 암호문의 base64 연결이에요.
Vault는 이 데이터 중 어떤 것도 저장하지 않는다는 점을 기억하세요. 호출자가 암호화된 암호문을 저장할 책임이 있어요. 호출자가 plaintext를 원할 때는 값을 복호화하기 위해 암호문을 Vault에 다시 제공해야 해요.
Vault HTTP API는 서비스 거부 공격을 막기 위해 최대 요청 크기 32MB를 부과해요. 이는 Vault 서버 구성의 listener 블록별로 조정할 수 있어요.
2. 이름 있는 키로 /decrypt 엔드포인트를 사용해 데이터를 복호화합니다.
$ vault write transit/decrypt/my-key ciphertext=vault:v1:8SDd3WHDOjf7mq69CyCqYjBXAiQQAVZRkFM13ok481zoCmHnSeDX9vyf7w==
Key Value
--- -----
plaintext bXkgc2VjcmV0IGRhdGEK
결과 데이터는 base64로 인코딩돼 있어요(이유에 대한 자세한 내용은 위 참고 참고). 디코드해 원시 plaintext를 얻으세요.
$ base64 --decode <<< "bXkgc2VjcmV0IGRhdGEK"
my secret data
영리한 셸 스크립팅으로 한 명령에 이 복호화를 스크립트화할 수도 있어요.
$ vault write -field=plaintext transit/decrypt/my-key ciphertext=... | base64 --decode
my secret data
ACL을 사용하면 신뢰할 수 있는 운영자가 이름 있는 키를 관리하고, 애플리케이션이 접근해야 하는 이름 있는 키로만 암호화·복호화할 수 있도록 transit 시크릿 엔진 사용을 제한할 수 있어요.
3. 기본 암호화 키를 회전합니다. 이렇게 하면 새 암호화 키가 생성되어 이름 있는 키의 키링에 추가돼요.
$ vault write -f transit/keys/my-key/rotate
Success! Data written to: transit/keys/my-key/rotate
미래의 암호화는 이 새 키를 사용하게 돼요. 키 링을 사용하므로 옛 데이터는 여전히 복호화할 수 있어요.
4. 이미 암호화된 데이터를 새 키로 업그레이드합니다. Vault는 키링의 적절한 키로 값을 복호화한 다음 결과 plaintext를 키링의 최신 키로 암호화해요.
$ vault write transit/rewrap/my-key ciphertext=vault:v1:8SDd3WHDOjf7mq69CyCqYjBXAiQQAVZRkFM13ok481zoCmHnSeDX9vyf7w==
Key Value
--- -----
ciphertext vault:v2:0VHTTBb2EyyNYHsa3XiXsvXOQSLKulH+NqS4eRZdtc2TwQCxqJ7PUipvqQ==
이 과정은 plaintext 데이터를 드러내지 않아요. 따라서 Vault 정책은 거의 신뢰할 수 없는 프로세스에도 암호화된 데이터를 "rewrap"할 수 있는 능력을 부여할 수 있어요. 그 프로세스는 plaintext 데이터에 접근할 수 없기 때문이에요.
나만의 키 가져오기 (Bring your own key, BYOK)
참고: 키 가져오기 기능은 HSM이나 다른 외부 시스템에서 기존 키를 가져와야 하는 경우를 지원해요. Vault 안에서 Transit이 키를 생성하고 관리하게 하는 것이 더 안전해요.
명령줄을 통해 (Via the Command Line)
Vault 명령줄 도구에는 아래 수동 과정의 단계를 수행하는 헬퍼가 포함돼 있어요.
API를 통해 (Via the API)
먼저 transit에서 래핑 키(wrapping key)를 읽어야 해요.
$ vault read transit/wrapping_key
래핑 키는 4096비트 RSA 공개 키일 거예요.
그런 다음 아래 설명대로 import 엔드포인트의 암호문 입력을 만드는 데 래핑 키를 사용해요. 아래에서 대상 키(target key)는 가져오는 키를 가리켜요.
HSM
PKCS#11을 지원하는 HSM에서 키를 가져오는 경우 두 가지 시나리오가 가능해요.
- HSM이 CKM_RSA_AES_KEY_WRAP 메커니즘을 지원하면, 래핑 키를 사용해 대상 키를 래핑하는 데 사용할 수 있어요.
- 그렇지 않으면 두 메커니즘을 결합해 대상 키를 래핑할 수 있어요. 먼저 256비트 AES 키를 생성한 다음 CKM_AES_KEY_WRAP_KWP 메커니즘으로 대상 키를 래핑해요. 그런 다음 CKM_RSA_PKCS_OAEP 메커니즘(MGF1과 SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 중 하나 사용)으로 AES 키를 래핑 키 아래에 래핑해요.
암호문은 래핑된 AES 키 뒤에 래핑된 대상 키를 이어 붙여 구성해요.
암호문 바이트는 base64로 인코딩되어야 해요.
수동 과정 (Manual process)
대상 키가 HSM이나 KMS에 저장되지 않았다면 다음 단계로 import 엔드포인트 입력의 암호문을 구성할 수 있어요.
- 일회성 256비트 AES 키를 생성해요.
- AES-KWP로 일회성 AES 키를 사용해 대상 키를 래핑해요.
참고: 대칭 키(AES나 ChaCha20 키 같은)를 래핑할 때는 키의 원시 바이트를 래핑해요. 예를 들어 128비트 AES 키라면 길이 16자의 바이트 배열이 base64나 다른 인코딩 없이 직접 래핑돼요. 비대칭 키(RSA나 ECDSA 키 같은)를 래핑할 때는 이 키의 PKCS8 인코딩 형식을 원시 DER/바이너리 형태로 래핑해요. 암호화 전에 이 blob에 PEM 인코딩을 적용하지 말고 base64 인코딩도 하지 마세요.
- RSAES-OAEP(MGF1과 SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 중 하나)로 Vault 래핑 키 아래에 AES 키를 래핑해요.
- 일회성 AES 키를 삭제해요.
- 래핑된 AES 키 뒤에 래핑된 대상 키를 이어 붙여요.
- 결과를 base64로 인코딩해요.
transit으로 가져올 키를 래핑하는 자세한 내용은 키 래핑 가이드를 참고하세요.
튜토리얼 (Tutorial)
Encryption as a Service: Transit Secrets Engine 튜토리얼을 참고해 transit 시크릿 엔진으로 전송 중 데이터에 대한 암호 함수를 처리하는 방법을 배워 보세요.
API
Transit 시크릿 엔진은 완전한 HTTP API를 제공해요. 자세한 내용은 Transit 시크릿 엔진 API 문서를 참고해 주세요.
Terraform
Vault Terraform 프로바이더로 Transit 시크릿 리소스를 프로그래밍 방식으로 관리할 수 있어요. 자세한 내용은 Terraform Registry 문서를 참고하세요.