Transform 시크릿 엔진

Transform 시크릿 엔진

Advanced Data Protection Transform (ADP-Transform) 모듈이 있는 Vault Enterprise 또는 HCP Vault Dedicated 클러스터가 필요해요.

Transform 시크릿 엔진은 제공된 입력 값에 대해 안전한 데이터 변환과 토큰화를 처리해요. 변환 방법은 FF3-1을 통한 형식 보존 암호화(FPE) 같은 NIST 검증 암호 표준을 포함할 수 있지만, 마스킹 같은 다른 수단을 통한 데이터의 가명(pseudonymous) 변환일 수도 있어요.

이 시크릿 엔진은 현재 데이터 변환 유형으로 fpe, masking, tokenization을 지원해요.

출처: 문서

본문

설정 (Setup)

대부분의 시크릿 엔진은 본래 기능을 수행하기 전에 미리 설정을 해 둬야 해요. 이 단계들은 보통 운영자나 설정 관리 도구가 수행해요.

1. Transform 시크릿 엔진을 활성화합니다.

$ vault secrets enable transform
Success! Enabled the transform secrets engine at: transform/

기본적으로 시크릿 엔진은 엔진 이름과 같은 경로에 마운트돼요. 다른 경로에 활성화하려면 -path 인자를 사용하면 됩니다.

2. 이름 있는 역할을 만듭니다.

$ vault write transform/role/payments transformations=ccn-fpe
Success! Data written to: transform/role/payments

3. 변환(transformation)을 만듭니다.

$ vault write transform/transformations/fpe/ccn-fpe \
  template=ccn \
  tweak_source=internal \
  allowed_roles=payments
Success! Data written to: transform/transformations/fpe/ccn-fpe

4. (선택) 템플릿을 만듭니다.

$ vault write transform/template/ccn \
  type=regex \
  pattern='(\d{4})[- ](\d{4})[- ](\d{4})[- ](\d{4})' \
  encode_format='$1-$2-$3-$4' \
  decode_formats=last-four='$4' \
  alphabet=numerics
Success! Data written to: transform/template/ccn

5. (선택) 알파벳을 만듭니다.

$ vault write transform/alphabet/numerics \
    alphabet="0123456789"
Success! Data written to: transform/alphabet/numerics

사용법 (Usage)

시크릿 엔진이 설정되고 사용자/머신이 적절한 권한을 가진 Vault 토큰을 갖게 되면, 이 시크릿 엔진을 사용해 입력 값을 인코딩·디코딩할 수 있어요.

1. 이름 있는 역할로 /encode 엔드포인트를 사용해 일부 입력 값을 인코딩합니다.

$ vault write transform/encode/payments value=1111-2222-3333-4444
Key              Value
---              -----
encoded_value    9300-3376-4943-8903

역할에 변환이 두 개 이상 있으면 변환을 제공해야 해요. 변환의 tweak 소스가 "supplied"이면 tweak을 제공해야 해요.

2. 이름 있는 역할로 /decode 엔드포인트를 사용해 일부 입력 값을 디코딩합니다.

$ vault write transform/decode/payments value=9300-3376-4943-8903
Key              Value
---              -----
decoded_value    1111-2222-3333-4444

역할에 변환이 두 개 이상 있으면 변환을 제공해야 해요. 변환의 tweak 소스가 "supplied" 또는 "generated"이면 tweak을 제공해야 해요.

3. 이름 있는 역할과 디코드 형식으로 /decode 엔드포인트를 사용해 일부 입력 값을 디코딩합니다.

$ vault write transform/decode/payments/last-four value=9300-3376-4943-8903
Key              Value
---              -----
decoded_value    4444

역할에 변환이 두 개 이상 있으면 변환을 제공해야 해요. 변환의 tweak 소스가 "supplied" 또는 "generated"이면 tweak을 제공해야 해요. 디코드 형식은 선택적으로 제공할 수 있어요. 제공하지 않으면 이전 예시처럼 디코드 출력이 템플릿의 패턴과 일치하도록 형식화돼요.

역할, 변환, 템플릿, 알파벳

Transform 시크릿 엔진은 데이터 변환을 수행하는 데 필요한 정보의 여러 측면을 담는 여러 유형의 리소스를 포함해요.

  • **역할(Roles)**은 수행이 허용된 변환 집합을 담는 기본적인 상위 수준 구조예요. 인코드와 디코드 작업을 수행할 때 역할 이름이 제공돼요.
  • **변환(Transformations)**은 특정 변환에 대한 정보를 담아요. 수행하려는 변환 유형, 값 감지를 위해 사용할 템플릿, tweak 소스나 사용할 마스킹 문자 같은 변환별 값에 대한 정보를 포함해요.
  • **템플릿(Templates)**은 변환하려는 값을 무엇을 어떻게 캡처할지 결정하게 해 줘요.
  • **알파벳(Alphabets)**은 FPE 변환에서 입력 값과 변환된 값 양쪽에 포함된 유효 UTF-8 문자 집합을 제공해요.

변환 (Transformations)

형식 보존 암호화 (Format preserving encryption)

형식 보존 암호화(FPE)는 FF3-1을 통해 암호학적으로 안전한 변환을 수행해 입력 값을 인코딩하면서도 데이터 형식과 길이를 유지해요. FF3-1은 AES-256을 암호화에 사용하는 구성이에요.

Tweak과 tweak 소스

FF3-1은 암호화·복호화 작업 수행 시 암호문과 함께 기밀성이 아닌 파라미터인 tweak을 사용해요. tweak은 정확히 7바이트 값이에요. 시크릿 엔진은 이 값이 필요할 때마다 인코드·디코드 작업에 이 값의 base64 인코딩 문자열을 사용해요.

인코딩·디코딩 작업의 흐름을 단순화하기 위해, 변환 생성이 tweak 값의 생성과 연결을 처리할 수 있어요. 이렇게 하면 애플리케이션이 다른 메타데이터를 생성하거나 저장할 필요 없이 단일 값을 제공할 수 있어요.

더 세분화된 제어가 필요한 경우 tweak 값은 Vault가 생성해 반환하거나, 독립적으로 생성해 제공할 수 있어요.

요약하면 tweak 값을 소싱하는 방법은 세 가지가 있어요.

  • supplied — FPE 변환의 기본 동작이에요. tweak 값은 외부에서 생성되어 인코드·디코드 작업에 제공되어야 해요.
  • generated — 시크릿 엔진이 인코드 작업에서 tweak 값을 생성하고 인코드된 값과 함께 응답의 일부로 반환해요. 인코드된 값을 디코딩할 때 다시 제공할 수 있도록 이 값을 앱이 저장하는 것은 앱의 몫이에요.
  • internal — 시크릿 엔진이 변환당 내부 tweak 값을 생성해요. 이 값은 변환의 모든 인코드·디코드 작업에 재사용되므로 인코드·디코드 작업에서 반환되지 않아요. 데이터셋의 고유성에 따라 이 모드는 더 높은 위험을 도입할 수 있지만, 값을 별도로 저장할 필요가 없어 가장 편리해요. 이 모드는 인코딩되는 값이 충분히 고유할 때만 사용해야 해요.

팀과 조직은 어떤 tweak 소스를 사용할지 선택할 때 트레이드오프를 저울질해야 해요. suppliedinternal 소싱에 대해서는 FF3-1 Tweak 사용 세부 사항을 참고하세요.

입력 한도 (Input limits)

FF3-1은 입력 길이에 최소·최대 한도를 모두 지정해요. 이 한도는 보안 목표에 의해 결정되며, 주어진 알파벳에 대해 입력 크기가 무차별 대입으로 추측 가능해지지 않도록 보장해요.

길이 A의 알파벳이 주어졌을 때, 다음 조건이면 입력 길이 L이 유효해요.

  • L >= 2,
  • A^L >= 1,000,000
  • L <= 2 * floor(log_A(2^96))

구체적인 예로 신용카드 번호를 처리할 때 A는 10, L은 16이므로 유효 입력 길이는 6~56자 사이예요. 이는 10^6=1,000,000(이미 2보다 큼)이고 2 * floor(log_10(2^96)) = 56이기 때문이에요.

물론 신용카드 번호의 경우 유효 입력은 항상 12~19자리 십진수일 거예요.

출력 한도 (Output limitations)

템플릿에 의한 변환과 형식화 후 값은 형식이 보존된 입력의 암호화된 버전이에요. 그러나 값 자체는 다른 표준에 대해 유효하지 않을 수 있어요. 예를 들어 출력 신용카드 번호는 검증되지 않을 수 있어요(유효한 체크 디지트를 만들지 못할 가능성이 큼).

그러므로 출력을 저장할 때 스토리지의 검증이 이를 거부할 수 있는지 고려해야 해요.

마스킹 (Masking)

마스킹은 입력 값의 일치하는 문자를 원하는 문자로 교체해요. 이 변환 형태는 비가역적이라 디코드 작업으로 원래 값을 검색할 수 없어요.

토큰화 (Tokenization)

토큰화는 민감한 값을 *토큰(token)*이라는 관련 없는 값으로 교환해요. 원래 민감한 값은 토큰만으로는 복구할 수 없으며, 비가역적이에요.

입력 (Inputs)

토큰화 입력은 입력의 내용이나 형식을 보존하지 않으므로 템플릿이나 알파벳으로 처리되지 않아요.

출력 (Outputs)

토큰화는 형식 보존이 아니에요. 토큰 출력은 관련 없는 길이의 Base58 인코딩 문자열 값이며 템플릿으로 렌더링되지 않아요.

디코드된 값은 인코딩 전 그대로 verbatim 반환돼요.

메타데이터 (Metadata)

토큰화는 형식 보존이 아니고 상태 저장(stateful)이므로 입력 값은 Vault 요청 처리의 다른 한도에 따라 어떤 길이든 될 수 있어요. 또한 비민감한 메타데이터를 값과 함께 인코딩할 수 있고, 원래 값과 함께 또는 독립적으로 검색할 수 있어요.

작업 (Operations)

인코드·디코드 외에도 토큰화는 상태 저장이므로 두 가지 추가 작업을 제공해요.

  • 토큰이 주어지면 메타데이터 검색하기.
  • 입력 값이 유효하고 만료되지 않은 토큰을 갖는지 확인하기.
  • 일부 구성에서는 plaintext 입력에 대해 이전에 인코딩된 토큰 검색하기.
저장소 (Stores)

토큰화는 상태 저장이에요. 토큰화된 상태는 내부(기본값) 또는 외부 저장소에 저장될 수 있어요. 현재 외부 저장으로 PostgreSQL, MySQL, MSSQL만 지원돼요.

매핑 모드 (Mapping modes)

토큰화는 값의 안전성을 높이는 암호 구성으로 인코드 작업 결과를 스토리지에 저장해요. default 매핑 모드에서 토큰 자체는 변환 키와 토큰 요소를 포함하는 단방향 함수로 변환돼요. Vault는 토큰을 저장하지 않으므로 Vault 스토리지의 값 자체로는 원래 입력을 검색할 수 없어요.

두 번째 매핑 모드인 exportable은 운영자가 긴급 상황에서 export 작업을 통해 디코드된 입력 전체 집합을 복구해야 할 수 있는 경우를 위해 제공돼요. 가능하면 default 모드를 사용하는 것을 강력히 권장해요. 더 많은 공격 유형에 저항하기 때문이에요.

수렴형 토큰화 (Convergent tokenization)

참고: 수렴형 토큰화는 가져온 키(imported keys)가 있는 변환에는 지원되지 않아요.

또한 토큰화 변환은 *수렴형(convergent)*으로 구성될 수 있어요. 이는 plaintext와 만료를 두 번 이상 토큰화하면 같은 토큰 값이 된다는 뜻이에요. 수렴을 활성화하면 성능과 보안 고려 사항이 있어요.

삭제 동작 (Deletion behavior)

역할을 제외한 리소스의 삭제는, 이 정보 비트에 의존해 원래 값을 디코드·재구성할 수 있는 인코드된 값의 우발적 데이터 손실을 피하기 위해, 다른 관련 리소스가 현재 사용 중인지 확인함으로써 보호돼요. 변환 자체에 대한 정보가 변환 객체와 관련 리소스에 포함되어 있으므로 역할 삭제는 안전하게 수행할 수 있어요.

리소스를 삭제할 때 다음 규칙이 적용돼요.

  • 변환이 역할에 사용 중이면 삭제할 수 없어요.
  • 템플릿이나 저장소가 변환에 사용 중이면 삭제할 수 없어요.
  • 알파벳이 템플릿에 사용 중이면 삭제할 수 없어요.

제공되는 내장 리소스 (Provided builtin resources)

시크릿 엔진은 흔한 것으로 간주되는 일련의 내장 템플릿과 알파벳을 제공해요. 내장 템플릿은 삭제할 수 없고, 템플릿·알파벳 이름의 "builtin/" 접두사는 예약 키워드예요.

템플릿 (Templates)

시크릿 엔진에서 사용할 수 있는 내장 템플릿은 다음과 같아요.

  • builtin/creditcardnumber
  • builtin/socialsecuritynumber

이 템플릿들은 일치하는 패턴만 확인하고 값 자체의 유효성은 확인하지 않는다는 점을 기억하세요. 예를 들어 내장 신용카드 번호 템플릿은 제공된 값이 흔히 발급되는 신용카드 형식인지 판단할 수 있지만, 특정 발급자의 유효한 신용카드 번호인지는 판단할 수 없어요.

템플릿은 현재 일치 패턴 유형으로 정규식만 허용해요. Go의 표준 라이브러리를 regexp 엔진으로 사용하며, RE2 구문을 지원해요.

참고: builtin/any 템플릿은 토큰화 변환의 기본값이며 유일하게 유효해요.

알파벳 (Alphabets)

시크릿 엔진에서 사용할 수 있는 내장 알파벳은 다음과 같아요.

  • builtin/numeric
  • builtin/alphalower
  • builtin/alphaupper
  • builtin/alphanumericlower
  • builtin/alphanumericupper
  • builtin/alphanumeric

사용자 정의 알파벳은 2~65536개의 고유 문자를 포함해야 해요.

저장소 (Stores)

토큰화 변환에서 사용할 수 있는(그리고 기본값인) 내장 저장소는 다음과 같아요.

  • builtin/internal

튜토리얼 (Tutorial)

Transform 시크릿 엔진 튜토리얼을 참고해 제공된 시크릿에 대해 안전한 데이터 전송과 토큰화를 처리하는 방법을 배워 보세요.

나만의 키 가져오기 (Bring your own key, BYOK)

참고: 키 가져오기 기능은 HSM이나 다른 외부 시스템에서 기존 키를 가져와야 하는 경우를 지원해요. Vault 안에서 Transform이 키를 생성하고 관리하게 하는 것이 더 안전해요.

명령줄을 통해 (Via the Command Line)

Vault 명령줄 도구에는 아래 수동 과정에서 설명하는 단계를 수행하는 헬퍼가 포함돼 있어요.

API를 통해 (Via the API)

먼저 Transform 시크릿 엔진에서 래핑 키(wrapping key)를 읽어야 해요.

$ vault read transform/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 엔드포인트 입력의 암호문을 구성할 수 있어요.

  1. 일회성 256비트 AES 키를 생성해요.
  2. AES-KWP로 일회성 AES 키를 사용해 대상 키를 래핑해요.
  3. RSAES-OAEP(MGF1과 SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 중 하나)로 Vault 래핑 키 아래에 AES 키를 래핑해요.
  4. 일회성 AES 키를 삭제해요.
  5. 래핑된 AES 키 뒤에 래핑된 대상 키를 이어 붙여요.
  6. 결과를 base64로 인코딩해요.

키 래핑 과정에 대한 자세한 내용은 키 래핑 가이드를 참고하세요(Transform 시크릿 엔진으로 가져올 키를 래핑할 때는 transform 래핑 키를 사용해야 해요).

API

Transform 시크릿 엔진은 완전한 HTTP API를 제공해요. 자세한 내용은 Transform 시크릿 엔진 API 문서를 참고해 주세요.

더 알아보기 (Learn more)