제 8 장: 암호학과 서명
본 장은 CAP 프로토콜이 사용하는 서명 알고리즘, 키 형식, 키 라이프사이클 관리 및 배포 요구사항을 정의한다. 본 장의 암호학 요구사항은 규범적이다 — CAP 프로토콜에 적합한 모든 구현은 MUST 본 장 정의에 따라 실시한다.
8.1 알고리즘 집합
CAP v1은 강제 구현의 서명 알고리즘과 키 형식을 두 세트 정의한다:
| 알고리즘 ID | 알고리즘 | 공개 키 길이 | 서명 길이 | 상태 |
|---|---|---|---|---|
ed25519 | Ed25519(RFC 8032) | 32 바이트 | 64 바이트 | 필수 구현 |
ecdsa-p256-sha256 | ECDSA P-256 + SHA-256(RFC 6979) | 65 바이트(미압축) / 33 바이트(압축) | 64 바이트(DER 인코딩 또는 raw) | 필수 구현 |
모든 CAP 구현은 MUST 이 두 세트의 알고리즘을 동시에 지원한다. Trusted_Ticket이 JWS를 사용하는 경우, 대응하는 알고리즘 명칭은:
| CAP 알고리즘 ID | JWS alg 필드 |
|---|---|
ed25519 | EdDSA |
ecdsa-p256-sha256 | ES256 |
8.1.1 알고리즘 선택 권장
ed25519우선 사용: 성능이 더 좋고, 서명이 더 짧으며, 키 관리가 더 간단함ecdsa-p256-sha256: FIPS 140-3 등 규제 요구사항 하에서 사용
발급자는 SHOULD 모든 신규 발급 자격 증명에서 기본적으로 ed25519를 사용한다, 명시적 준수 요구사항이 있는 경우 제외.
8.1.2 허용되지 않는 알고리즘
CAP v1 구현은 MUST NOT 다음 알고리즘으로 신규 자격 증명을 발급하거나 수용한다:
- 임의의 RSA 서명 변형(성능 불량, 키가 더 큼)
- ECDSA secp256k1(비 FIPS 표준 곡선)
- ECDSA P-384 / P-521(v1에서는 강제하지 않음, 향후 버전에서 추가될 수 있음)
- 임의의 SHA-1 파생 서명 알고리즘
8.2 키 형식
8.2.1 Ed25519
공개 키는 RFC 8032 §5.1.5에 따라 인코딩:
- 32 바이트 리틀 엔디안의 압축 Edwards 곡선 점
DescriptorPayload의 signature.signature_value는 64 바이트의 원시 서명(ASN.1 인코딩 미포함).
JWS의 서명은 RFC 8037에 따라 인코딩, 64 바이트의 원시 서명을 base64url 인코딩.
8.2.2 ECDSA P-256
공개 키는 RFC 5480에 따라 인코딩:
- 미압축 형식: 65 바이트(0x04 || X || Y)
- 압축 형식: 33 바이트(0x02/0x03 || X)
구현은 MUST 미압축 및 압축 형식의 공개 키를 모두 수용한다.
서명 형식:
- DescriptorSignature 내: 64 바이트의 원시 서명(R || S, 각 부분 32 바이트 빅 엔디안), DER 미사용
- JWS 내: RFC 7518 §3.4에 따라 인코딩(64 바이트 R || S)
8.2.3 키의 바이너리 표현
VerificationKey.key_material 필드는 위 형식의 바이트 시퀀스를 직접 보관한다:
- ed25519 → 32 바이트
- ecdsa-p256-sha256(미압축) → 65 바이트
- ecdsa-p256-sha256(압축) → 33 바이트
8.3 서명 입력 구축
8.3.1 Authorization_Descriptor 서명 입력
다음 단계로 서명 입력을 구축한다:
AuthorizationDescriptor.payload(DescriptorPayload 구조)를 가져옴- RFC 8949 CBOR 결정적 인코딩(Deterministic Encoding)으로 바이트 시퀀스로 시리얼라이즈
- 해당 바이트 시퀀스가 서명 알고리즘의 입력이 됨
CBOR 결정적 인코딩의 핵심 제약(RFC 8949 §4.2 유래):
- map의 키는 사전 순으로 정렬
- 수치는 최단 인코딩 사용
- 문자열과 바이트열은 최단 길이 인코딩 사용
- 불확정 길이 인코딩(indefinite-length encoding) 미사용
구현은 MUST 이러한 제약을 엄격히 준수하여 구현 간 서명 검증 일관성을 보장한다.
8.3.2 Trusted_Ticket 서명 입력
RFC 7515 §5.1에 따라 JWS 서명 입력을 구축:
Signing Input = base64url(UTF8(Header)) + "." + base64url(UTF8(Payload))
여기서:
- Header와 Payload는 RFC 7159에 따라 UTF-8 JSON으로 시리얼라이즈
- JSON 필드 순서: 구현은 SHOULD 키를 사전 순으로 정렬하지만, 엄격한 필드 순서 요구사항은 base64url 인코딩 바이트로 결정됨
8.3.3 RevocationStatement 서명 입력
폐기 선언의 서명 입력 구축은 Authorization_Descriptor와 동일하다:
signature필드를 제거하고, 나머지 RevocationStatement 필드를 보존- CBOR 결정적 인코딩 시리얼라이제이션
- 바이트 시퀀스를 서명 입력으로 함
8.4 키 배포
8.4.1 배포 모드
단말은 MUST 다음 두 종류의 Verification_Key 배포 모드를 지원한다:
오프라인 프리인스톨(Pre-installed)
단말 출고 시 또는 배포 시 초기 Verification_Key를 프리인스톨한다. 프리인스톨 키:
VerificationKey구조에서source = "pre-installed"로 표시- MUST 제조 또는 배포 단계에서 물리적 또는 통제된 보안 채널을 통해 기록
- 통상 루트 레벨 Descriptor_Issuer(장치 벤더 인증 Issuer 등)에 대응
온라인 배포(RA-distributed)
Registration_Authority가 온라인 인터페이스를 통해 새 Verification_Key를 배포한다:
VerificationKey구조에서source = "ra-distributed"로 표시- MUST TLS/mTLS 채널을 통해 전송(§1.3.4 참조)
- 단말은 MUST 전송자가 신뢰된 Registration_Authority임을 검증
8.4.2 신뢰 앵커 구성
단말의 Registration_Authority 공개 키(RA 푸시 메시지의 서명 검증에 사용)는 신뢰 앵커로서:
- MUST 단말 제조 또는 초기 배포 시 프리인스톨됨
- 물리적 또는 통제된 채널로만 교체 가능
- CAP 프로토콜 런타임 메커니즘으로 갱신하지 않음
8.4.3 배포 메시지
Registration_Authority가 푸시하는 키 배포 메시지:
VerificationKeyDistribution {
required version : uint32 (= 1)
required key : VerificationKey
required ra_signature : DescriptorSignature // Registration_Authority에 의한 서명
}
단말 처리 흐름:
ra_signature가 신뢰 앵커 Registration_Authority에 의해 발급된 것인지 검증key.algorithm이 §8.1에서 허용된 알고리즘 집합 내에 있음을 검증key.valid_from이 단말의 현재 시각과 합리적인지 검증(현재 시각 +24 시간을 초과하지 않음 등)- 단말 키 보관소에 기록
- Registration_Authority에 확인 반환(확인 메커니즘은 본 사양의 범위 외)
8.5 키 보관
단말은 MUST 모든 Verification_Key와 로컬 서명 키(§4.4.3 참조)를 안전하게 보관한다.
8.5.1 보관 요구사항
단말은 MUST:
- 모든 키의 개인 키 부분을 암호화 보관(공개 키는 평문 보관 가능)
- 개인 키 접근은 OS 프로세스 권한으로 보호되며, Protocol_Engine만 읽기 가능
- SHOULD 개인 키를 하드웨어 보안 요소(TPM, Secure Enclave, TEE 등)에 보존
단말은 MUST NOT:
- 평문 형식으로 개인 키를 영속화 매체에 기록
- 개인 키를 CAP 프로토콜 메시지로 전송
- 디버그 로그 또는 에러 출력에서 개인 키 내용 노출
8.5.2 키 누출 처리
단말이 키 누출 가능성을 감지한 경우(안전 보관이 공격받은 경우 등):
- 즉시 해당 키 사용 중단
- §8.6 흐름을 통해 Registration_Authority에 보고
- 새 키 배포 완료 전, 관련 자격 증명의 검증을 모두 거부(보수적 정책)
8.6 키 갱신과 로테이션
8.6.1 원활한 전환
Registration_Authority는 Verification_Key 로테이션 시 MUST 원활한 전환을 제공한다:
- 새 키를 모든 단말에 배포
- 전환 기간 중(기본 30 일), 신구 키가 병존하며 유효
- 전환 기간 종료 후, 구 키의
valid_until이 도래하여 자동 실효
단말은 전환 기간 중 MUST 신구 키를 동시에 유지하고, key_id에 따라 대응하는 키를 선택하여 검증한다.
8.6.2 긴급 폐기
VerificationKeyRevocation {
required version : uint32 (= 1)
required key_id : string
required revocation_time : timestamp
required reason : enum["compromised", "superseded", "ra_decision"]
required ra_signature : DescriptorSignature
}
단말은 폐기 메시지 수신 후 MUST:
- 서명이 신뢰 앵커 Registration_Authority 유래임을 검증
- 즉시 해당 key_id를 폐기됨으로 표시
- 후속 검증 요청에서 해당 key_id를 사용하는 자격 증명을 모두 거부(
E_VERIFICATION_KEY_INVALID반환) - 모든 활성 Session을 능동 확인: 해당 key_id로 발급된 자격 증명을 사용하는 Session을 강제 종료(§5.5 참조)
8.6.3 단말 로컬 서명 키의 로테이션
단말이 §4.4 변환 흐름을 지원하기 위해 보유하는 로컬 서명 키:
- 90 일마다 SHOULD 자동 로테이션
- 로테이션 시 단말이 새 키 쌍을 생성, 구 키는 발급된 자격 증명의 검증용으로 모두 만료될 때까지 계속 사용
- 단말은 MAY 최대 4 개의 로컬 서명 키를 동시에 보유 가능(최대 유효 기간 + 원활한 전환 커버)
8.7 암호학 요구사항 요약
| 요구사항 | 범위 |
|---|---|
| 서명 알고리즘은 MUST ed25519 / ecdsa-p256-sha256 중에서 선택 | 모든 서명 시나리오 |
| 개인 키는 MUST 안전 보관 | 모든 발급자와 단말 |
| 공개 키 배포는 MUST 암호화 채널을 통과 | Registration_Authority → 단말 |
| 신뢰 앵커는 MUST 물리적 또는 통제된 채널로 프리인스톨 | 모든 단말 |
| CBOR 결정적 인코딩을 오프라인 자격 증명 서명 입력에 사용 | Authorization_Descriptor, RevocationStatement |
| JWS Compact Serialization을 온라인 티켓에 사용 | Trusted_Ticket |
