Vault의 PKCS#11 지원
Vault의 PKCS#11 지원
PKCS11 provider는 KMIP 시크릿 엔진의 일부이며, 고급 데이터 보호(ADP, Advanced Data Protection) 모듈이 포함된 Vault Enterprise가 필요합니다. PKCS11 provider는 키 생성, 암호화, 복호화, 키 저장 작업의 하위 집합을 지원합니다. PKCS11 provider를 사용하려면 Enterprise ADP-KM 라이선스가 있어야 합니다.
출처: 문서
본문
PKCS#11은 기기의 암호화 기능에 접근하는 수단을 제공하는 개방형 표준 C API입니다. 예를 들어 하드웨어 보안 모듈(HSM)(예: Yubikey)에 로컬 프로그램(예: GPG)에서 접근할 때 자주 사용됩니다.
Vault는 PKCS#11 라이브러리(또는 provider)를 제공하므로 Vault를 SSM(Software Security Module) 으로 사용할 수 있습니다. 이를 통해 사용자는 Vault를 다른 PKCS#11 기기처럼 취급해 PKCS#11 호출로 Vault에서 키·개체를 관리하고 암호화·복호화를 수행할 수 있습니다. PKCS#11 라이브러리는 Vault의 KMIP 시크릿 엔진에 연결되어 암호화 작업과 개체 저장을 제공합니다.
플랫폼 지원
이 라이브러리는 KMIP 시크릿 엔진과 함께 라이선스에 고급 데이터 보호 모듈이 포함된 Vault Enterprise 1.11+와 함께 작동합니다.
| 운영 체제 | 아키텍처 | 배포판 | glibc |
|---|---|---|---|
| Linux | x86-64 | RHEL 8 호환 | 2.28 |
| Linux | x86-64 | RHEL 9 호환 | 2.34 |
| Linux | x86-64 | RHEL 10 호환 | 2.34 |
| Linux | s390X | RHEL 9 호환 | 2.34 |
| Linux | s390X | RHEL 10 호환 | 2.34 |
| macOS | x86-64 | — | — |
| macOS | arm64 | — | — |
참고:
vault-pkcs11-provider는 모든 glibc 기반 Linux 배포판에서 실행됩니다. 위 버전은 RHEL 호환 GLIBC 버전으로 제공됩니다. 배포판의 glibc 버전에 대해 배포판이 제공하는 것과 같거나 더 오래된 버전에 대해 빌드된vault-pkcs11-provider를 선택하세요.
provider는 공유 C 라이브러리 형태로 제공되며, Linux에서는 libvault-pkcs11.so, macOS에서는 libvault-pkcs11.dylib입니다. releases.hashicorp.com에서 다운로드할 수 있습니다.
빠른 시작 (Quick start)
- provider를 사용하려면 KMIP 시크릿 엔진이 있는 Vault Enterprise 인스턴스에 접근할 수 있어야 합니다. 예를 들어
VAULT_LICENSE환경 변수에 라이선스가 있다면 로컬에서 시작할 수 있습니다.
docker pull hashicorp/vault-enterprise && docker run --name vault \
-p 5696:5696 \
-p 8200:8200 \
--cap-add=IPC_LOCK \
-e VAULT_LICENSE=$(printenv VAULT_LICENSE) \
-e VAULT_ADDR=http://127.0.0.1:8200 \
-e VAULT_TOKEN=root \
hashicorp/vault-enterprise \
server -dev -dev-root-token-id root -dev-listen-address 0.0.0.0:8200
- KMIP 시크릿 엔진과 KMIP 스코프(scope)를 구성합니다. 스코프는 키와 개체를 보관하는 데 사용됩니다.
참고: 이 명령은 자격증명을 평문으로 출력합니다.
vault secrets enable kmip
vault write kmip/config listen_addrs=0.0.0.0:5696
vault write -f kmip/scope/my-service
vault write kmip/scope/my-service/role/admin operation_all=true
vault write -f -format=json kmip/scope/my-service/role/admin/credential/generate | tee kmip.json
중요: 프로덕션에서 KMIP를 구성할 때
server_hostnames와server_ips구성 매개변수를 설정해야 할 것입니다. 그렇지 않으면 인증서 검증 오류로 KMIP 시크릿 엔진에 대한 TLS 연결이 실패합니다.
마지막 줄은 KMIP 서버에 연결하는 데 사용할 인증서, 키, CA 인증서 체인이 담긴 JSON 파일을 생성합니다. PKCS#11 provider가 사용할 수 있도록 파일로 저장해야 합니다.
jq --raw-output --exit-status '.data.ca_chain[]' kmip.json > ca.pem
jq --raw-output --exit-status '.data.certificate' kmip.json > cert.pem
KMIP 시크릿 엔진의 인증서 파일에는 키도 포함되어 있습니다.
vault-pkcs11.hcl구성 파일을 만듭니다.
slot {
server = "127.0.0.1:5696"
tls_cert_path = "cert.pem"
ca_path = "ca.pem"
scope = "my-service"
}
사용 가능한 모든 매개변수는 아래를 참고하세요.
-
KMIP 자격증명의 인증서를 구성 파일에 지정된 파일(예:
cert.pem,ca.pem)에 복사합니다. -
이제
libvault-pkcs11.so(또는.dylib) 라이브러리를 사용해 OpenSC의pkcs11-tool같은 PKCS#11 호환 도구로 Vault의 KMIP 시크릿 엔진에 접근할 수 있어야 합니다.
$ VAULT_LOG_FILE=/dev/null pkcs11-tool --module ./libvault-pkcs11.so -L
Available slots:
Slot 0 (0x0): Vault slot 0
token label : Token 0
token manufacturer : HashiCorp
token model : Vault Enterprise
token flags : token initialized, PIN initialized, other flags=0x60
hardware version : 1.12
firmware version : 1.12
serial num : 1234
pin min/max : 0/255
$ VAULT_LOG_FILE=/dev/null pkcs11-tool --module ./libvault-pkcs11.so --keygen -a abc123 --key-type AES:32 \
--extractable --allow-sw 2>/dev/null
Key generated:
Secret Key Object; AES length 32
VALUE:
label: abc123
Usage: encrypt, decrypt, wrap, unwrap
Access: none
VAULT_LOG_FILE=/dev/null 설정은 Vault PKCS#11 드라이버 로그가 stdout에 나타나는 것을 방지하기 위한 것입니다(기본적으로 파일을 지정하지 않으면 stdout에 표시됨). 프로덕션에서는 VAULT_LOG_FILE을 /var/log/vault.log 같은 더 영구적인 위치로 설정하는 것이 좋습니다.
구성 (Configuration)
PKCS#11 Provider는 HCL 파일과 환경 변수를 통해 구성할 수 있습니다.
HCL 파일에는 PKCS#11 기기 슬롯(논리 기기)을 Vault 인스턴스와 KMIP 스코프에 매핑하는 지시문이 포함되며, 라이브러리가 KMIP에(클라이언트 TLS 인증서로) 어떻게 인증할지 구성합니다. PKCS#11 라이브러리는 기본적으로 vault-pkcs11.hcl과 /etc/vault-pkcs11.hcl에서 이 파일을 찾거나, VAULT_KMIP_CONFIG 환경 변수를 설정해 재정의할 수 있습니다.
예를 들어:
slot {
server = "127.0.0.1:5696"
tls_cert_path = "cert.pem"
ca_path = "ca.pem"
scope = "my-service"
}
slot 블록은 첫 번째 PKCS#11 슬롯이 Vault를 가리키도록 구성합니다. 대부분의 프로그램은 슬롯 하나만 사용합니다.
server(필수): Vault 서버의 IP 또는 DNS 이름과 포트 번호(기본 5696)tls_cert_path(필수): KMIP 엔진에 인증하는 데 사용하는 클라이언트 TLS 인증서 위치tls_key_path(선택, 기본tls_cert_path의 값): KMIP 엔진에 인증하는 데 사용하는 암호화 또는 비암호화 TLS 키 위치ca_path(필수): 서버 인증서를 검증하는 데 사용할 CA 번들 위치scope(필수): 인증할 KMIP 스코프이자 TDE 마스터 키와 관련 메타데이터가 저장될 곳cache(선택, 기본 true): provider가C_GetAttributeValue(KMIP: GetAttributes) 호출 성능을 위해 캐시를 사용하는지 여부emulate_hardware(선택, 기본 false): provider가 하드웨어 기기에 연결되었다고 보고할지 여부
PKCS#11 라이브러리가 구성 파일을 찾는 기본 위치는 현재 디렉토리(vault-pkcs11.hcl)와 /etc/vault-pkcs11.hcl이지만, VAULT_KMIP_CONFIG 환경 변수를 어떤 파일로든 설정해 재정의할 수 있습니다.
환경 변수로도 이러한 매개변수와 그 이상을 구성할 수 있습니다.
VAULT_KMIP_CONFIG: HCL 구성 파일 위치. 기본적으로 provider는./vault-pkcs11.hcl과/etc/vault-pkcs11.hcl을 확인합니다.VAULT_KMIP_CERT_FILE: KMIP 엔진에 인증하는 데 사용하는 TLS 인증서 위치VAULT_KMIP_KEY_FILE: KMIP 엔진에 인증하는 데 사용하는 TLS 키 위치VAULT_KMIP_KEY_PASSWORD: 암호화된 경우 TLS 키 파일의 비밀번호VAULT_KMIP_CA_FILE: KMIP 엔진에 대한 연결 인증에 사용하는 TLS CA 번들 위치VAULT_KMIP_SERVER: 암호화와 저장에 사용할 KMIP 엔진의 주소와 포트VAULT_KMIP_SCOPE: 암호화와 저장에 사용할 KMIP 스코프VAULT_KMIP_CACHE:C_GetAttributeValue(KMIP: GetAttributes) 호출을 캐시할지 여부VAULT_LOG_LEVEL: provider가 사용할 로그 수준. 기본값은WARN. 유효한 값은TRACE,DEBUG,INFO,WARN,ERROR,OFF.VAULT_LOG_FILE: provider가 로깅에 사용할 파일 위치. 기본값은 표준 출력.VAULT_EMULATE_HARDWARE: provider가 하드웨어 기기로 지원된다고 보고할지 여부
암호화된 TLS 키 지원
KMIP 엔진이 반환하는 TLS 키는 기본적으로 암호화되어 있지 않습니다. 그러나 PKCS#11 provider는 키에 대해 RFC 1423을 사용하는 (제한된) 암호화 옵션을 지원합니다. 사용 가능한 알고리즘 중 AES-256-CBC만 권장합니다.
KMIP의 키는 ECDSA 키여야 하며, OpenSSL로 비밀번호로 암호화할 수 있습니다.
openssl ec -in cert.key -out encrypted.key -aes-256-cbc
PKCS#11 provider는 TLS 키를 복호화하려면 비밀번호에 접근해야 합니다. 비밀번호는 두 가지 방법으로 provider에 제공할 수 있습니다.
VAULT_KMIP_KEY_PASSWORD환경 변수, 또는- 암호화된 TLS 키를 복호화하려 시도할 때
C_LoginPKCS#11 함수의 "PIN" 매개변수
VAULT_KMIP_KEY_PASSWORD로는 단일 비밀번호만 제공할 수 있으므로, HCL 파일의 여러 슬롯이 암호화된 TLS 키를 사용한다면 같은 비밀번호로 암호화해야 하거나, C_Login 메서드를 사용해 비밀번호를 지정해야 합니다.
오류 처리 (Error handling)
오류가 발생하면 가장 먼저 VAULT_LOG_FILE에서 관련 오류 메시지를 확인하세요.
PKCS#11 provider가 0x30(CKR_DEVICE_ERROR) 오류 코드를 반환하면 C_SessionInfo 호출에서 추가 기기 오류 코드를 사용할 수 있습니다. provider가 반환하는 알려진 기기 오류 코드는 다음과 같습니다.
| 코드 | 의미 |
|---|---|
| 400 | 구성 또는 PKCS#11 호출에 잘못된 입력이 제공되었습니다. |
| 401 | 잘못된 자격증명이 제공되었습니다. |
| 404 | 개체, 속성, 또는 키를 찾을 수 없습니다. |
| 600 | 알 수 없는 I/O 오류가 발생했습니다. |
| 601 | KMIP 엔진 오류가 발생했습니다. |
기능 (Capabilities)
Vault PKCS#11 provider는 다음 PKCS#11 provider 프로필을 구현합니다.
- Baseline
- Extended
현재 지원되는 키 생성 메커니즘:
| 이름 | 메커니즘 번호 | Provider 버전 | Vault 버전 |
|---|---|---|---|
| RSA-PKCS | 0x0000 | 0.2.0 | 1.13 |
| AES key generation | 0x1080 | 0.1.0 | 1.12 |
현재 지원되는 암호화 메커니즘:
| 이름 | 메커니즘 번호 | Provider 버전 | Vault 버전 |
|---|---|---|---|
| RSA-PKCS | 0x0001 | 0.2.0 | 1.13 |
| RSA-PKCS-OAEP | 0x0009 | 0.2.0 | 1.13 |
| AES-ECB | 0x1081 | 0.2.0 | 1.13 |
| AES-CBC | 0x1082 | 0.1.0 | 1.12 |
| AES-CBC Pad | 0x1085 | 0.1.0 | 1.12 |
| AES-CTR | 0x1086 | 0.1.0 | 1.12 |
| AES-GCM | 0x1087 | 0.1.0 | 1.12 |
| AES-OFB | 0x2104 | 0.2.0 | 1.13 |
| AES-CFB128 | 0x2107 | 0.2.0 | 1.13 |
현재 지원되는 서명 메커니즘:
| 이름 | 메커니즘 번호 | Provider 버전 | Vault 버전 |
|---|---|---|---|
| RSA-PKCS | 0x0001 | 0.2.0 | 1.13 |
| SHA256-RSA-PKCS | 0x0040 | 0.2.0 | 1.13 |
| SHA384-RSA-PKCS | 0x0041 | 0.2.0 | 1.13 |
| SHA512-RSA-PKCS | 0x0042 | 0.2.0 | 1.13 |
| SHA224-RSA-PKCS | 0x0046 | 0.2.0 | 1.13 |
| SHA512-224-HMAC | 0x0049 | 0.2.0 | 1.13 |
| SHA512-256-HMAC | 0x004D | 0.2.0 | 1.13 |
| SHA256-HMAC | 0x0251 | 0.2.0 | 1.13 |
| SHA224-HMAC | 0x0256 | 0.2.0 | 1.13 |
| SHA384-HMAC | 0x0261 | 0.2.0 | 1.13 |
| SHA512-HMAC | 0x0271 | 0.2.0 | 1.13 |
- 암호화 및 복호화:
C_EncryptInit,C_Encrypt,C_EncryptUpdate,C_EncryptFinal,C_DecryptInit,C_Decrypt,C_DecryptUpdate,C_DecryptFinal - 키 관리:
C_GenerateKey,C_GenerateKeyPair,C_WrapKey,C_UnwrapKey,C_DeriveKey - 개체:
C_CreateObject,C_DestroyObject,C_GetAttributeValue,C_FindObjectsInit,C_FindObjects,C_FindObjectsFinal,C_SetAttributeValue,C_CopyObject,C_GetObjectSize - 관리:
C_Initialize,C_Finalize,C_Login(제공 시 PIN은 TLS 암호화 키의 패스프레이즈로 사용),C_Logout,C_GetInfo,C_GetSlotList,C_GetSlotInfo,C_GetTokenInfo,C_GetMechanismList,C_GetMechanismInfo,C_OpenSession,C_CloseSession,C_CloseAllSessions,C_GetSessionInfo,C_InitToken,C_InitPIN,C_SetPIN,C_GetOperationState,C_SetOperationState,C_GetFunctionStatus,C_CancelFunction,C_WaitForSlotEvent - 서명:
C_SignInit,C_Sign,C_SignUpdate,C_SignFinal,C_SignRecoverInit,C_SignRecover,C_VerifyInit,C_Verify,C_VerifyUpdate,C_VerifyFinal,C_VerifyRecoverInit,C_VerifyRecover - 다이제스트:
C_DigestInit,C_Digest,C_DigestUpdate,C_DigestKey,C_DigestFinal,C_DigestEncryptUpdate,C_DecryptDigestUpdate,C_SignEncryptUpdate,C_DecryptVerifyUpdate - 난수 생성(아래 참고):
C_SeedRandom,C_GenerateRandom
제한 사항 및 참고 (Limitations and notes)
Vault, KMIP 시크릿 엔진, PKCS#11의 특성 때문에 알아야 할 몇 가지 제한 사항이 있습니다.
C_FindObjects등이 반환하는 키·개체 ID는 각 세션에 대해 무작위화되며, 세션 간에 공유할 수 없고 세션이 닫힌 후에는 의미가 없습니다. PKCS#11 개체를 저장하는 데 사용되는 KMIP 개체는 긴 무작위 문자열을 ID로 가지지만, PKCS#11 개체 ID는 32비트 정수로 제한되기 때문입니다. 또한 PKCS#11 provider는 로컬 스토리지가 없습니다.- PKCS#11 provider의 성능은 Vault 서버까지의 지연시간과 성능에 크게 의존합니다. 거의 모든 PKCS#11 API 호출(일부 개체 속성 호출은 로컬로 캐시될 수 있음)이 1:1로 KMIP 호출로 번역되기 때문입니다. 여러 세션을 동시에 안전하게 사용할 수 있으며, 단일 Vault 서버 노드가 수천 개의 진행 중인 세션을 지원하는 것으로 테스트되었습니다.
- 개체 속성 캐시는 세션당 단일 개체에만 유효하며, 다른 개체의 속성이 조회되면 지워집니다.
- 난수 생성기 함수
C_GenerateRandom은 현재 Go의crypto/rand패키지를 호출해 라이브러리 내에서 소프트웨어로 구현되며, Vault를 호출하지 않습니다.
변경 로그 (Changelog)
- v0.2.3: IBM s390X CPU 아키텍처 지원 추가. EL7 지원 제거.
- v0.2.2: PKCS#11 클라이언트의 세션 풀 지원 수정. 개인 RSA 키의
C_GetAttributeValue버그 수정. 개인 RSA 키의 올바른 등록을 방해하던 버그 수정. 빅엔디안 아키텍처에서 provider 빌드 문제 수정. Go 1.25.4 및 Go 종속성 업데이트. - v0.2.1: Go 1.22.7 및 Go 종속성 업데이트. 산출물에 라이선스 파일 추가.
- v0.2.0: RSA 및 HMAC 작업 지원 도입.
- v0.1.3: Go 1.19.4 및 Go 종속성 업데이트. EL9 빌드에 누락된 체크섬 추가.
- v0.1.2: macOS arm64 지원 추가. Go 1.19.2 및 Go 종속성 업데이트.
- v0.1.1: KMIP: Vault 1.12가 요구하는 활성화 날짜 속성 설정. KMIP: 파기 전 키 폐지.
- v0.1.0: 최초 릴리스.