v0.6
AuditSyncPayload 동기화 프로토콜 및 3계층 무결성 체인 설계¶
1. 개요¶
1.1. 에어갭 증적 동기화의 설계 원칙¶
D'CENT Enterprise의 3-Zone 아키텍처에서 Zone 2(오프라인 앱)와 Zone 3(SE)는 물리적으로 네트워크에서 격리되어 있다. 따라서 감사 로그를 Zone 1(대시보드)으로 전달하기 위해서는 에어갭을 안전하게 넘는 배치 동기화 메커니즘이 필요하다.
핵심 원칙: 1. 에어갭 불가침: 동기화 데이터는 QR 코드 또는 NFC를 통해서만 전달한다. 네트워크 연결은 절대 사용하지 않는다. 2. 배치 전달: 실시간 스트리밍이 아닌 축적된 이벤트의 일괄 전달 방식을 사용한다. 3. UR 기반 인코딩: 기존 v0.5 MuSig2 QR 최적화 설계(Phase 27)에서 확립된 UR(Uniform Resource) 타입 패턴을 따른다. 4. Idempotent 수신: 동일 페이로드의 중복 수신을 안전하게 처리한다.
1.2. 채널 대역폭 제약¶
| 채널 | 단일 프레임 | 세션 최대 | 평균 동기화 적합성 |
|---|---|---|---|
| QR v40 | ~4,296 bytes | 멀티프레임 무한 (애니메이션) | 일반 동기화 (1-2 프레임) |
| NFC (ISO 14443) | ~256 bytes/블록 | ~32 KB/세션 | 대량 동기화 권장 |
1.3. 규제 근거¶
| 규제 | 요건 | 동기화 대응 |
|---|---|---|
| CORE-03 | 감사 로그 장기 보존 | AuditSyncPayload로 Zone 1에 전달 -> 3단계 아카이빙 |
| CORE-04 | 변조 불가 감사 로그 | SEAuditDigest 앵커 포함으로 변조 탐지 |
| REG-US-04 | 72시간 사이버보안 이벤트 보고 | 긴급 동기화 프로토콜로 즉시 전달 |
| REG-KR-14 | ISMS-P 변조 불가 감사 로그 | 3계층 교차 검증으로 무결성 증명 |
2. AuditSyncPayload UR 타입 정의¶
2.1. UR 타입 등록¶
- UR 타입:
ur:dcent-audit-sync - 네임스페이스: D'CENT Enterprise 전용 UR 타입 (Phase 27 패턴 준수)
- CBOR 인코딩: RFC 8949 준수
- UR 프레임워크: BC-UR (Blockchain Commons Uniform Resources) 기반 멀티파트 QR 지원
2.2. CDDL 스키마¶
; ====================================================================
; D'CENT Enterprise AuditSyncPayload Schema
; UR Type: ur:dcent-audit-sync
; Phase: 30-audit-architecture
; ====================================================================
AuditSyncPayload = {
version: uint .size 1, ; 스키마 버전 (1 byte)
payload_id: bstr .size 16, ; UUID, 중복 수신 방지 (idempotency key)
device_id: bstr .size 8, ; 발신 기기 (오프라인 앱) 식별자
sync_type: SyncType, ; 동기화 유형
se_digest: SEAuditDigest, ; 현재 SE 다이제스트 스냅샷 (128B)
sequence: SequenceInfo, ; 시퀀스 메타데이터
records: [* CompactAuditRecord], ; 압축된 감사 레코드 배열
prev_sync_hash: bstr .size 32, ; 이전 동기화 페이로드 해시
sync_sig: bstr .size 64, ; 오프라인 앱 서명 (전체 페이로드)
}
SyncType = &(
sync-normal: 1, ; 정상 주기적 동기화
sync-emergency: 2, ; 긴급 동기화 (보안 이벤트)
sync-bulk: 3, ; 대량 동기화 (장기 미동기화 후)
sync-partial: 4, ; 분할 동기화 (대량 데이터의 한 조각)
)
SequenceInfo = {
start_seq: uint, ; 시작 시퀀스 번호
end_seq: uint, ; 종료 시퀀스 번호
total_records: uint, ; 포함된 레코드 수
? part_index: uint, ; 분할 전송 시 파트 번호
? total_parts: uint, ; 분할 전송 시 총 파트 수
}
; CompactAuditRecord: AuditRecord의 전송 최적화 버전
; CBOR 필드 인덱스를 정수 키로 사용하여 크기 절감
CompactAuditRecord = {
0 => bstr .size 16, ; record_id
1 => uint, ; event_type (EventType 열거형)
2 => #6.1(float64), ; timestamp
3 => CompactActor, ; actor (압축)
4 => uint, ; zone (1/2/3)
5 => uint, ; result
6 => bstr .size 32, ; prev_hash
7 => bstr, ; payload (CBOR 인코딩된 EventPayload)
? 8 => bstr .size 64, ; signature (있는 경우)
}
CompactActor = {
0 => uint, ; role (RBACRole 열거형)
1 => bstr .size 8, ; device_id
? 2 => bstr .size 16, ; session_id (있는 경우)
? 3 => tstr, ; user_id (있는 경우)
}
2.3. 페이로드 크기 예산¶
| 동기화 유형 | 평균 레코드 수 | 평균 크기 | 최대 크기 | 권장 채널 |
|---|---|---|---|---|
| 정상 동기화 | 5-20 레코드 | ~1-2 KB | ~4 KB | QR (1-2 프레임) |
| 긴급 동기화 | 1-3 레코드 | ~200-500 B | ~1 KB | QR (1 프레임) |
| 대량 동기화 | 100+ 레코드 | ~10-30 KB | ~32 KB | NFC 권장 |
| 분할 동기화 | 파트당 20-30 | ~3-4 KB/파트 | ~4 KB/파트 | QR 멀티파트 |
크기 절감 기법: - CompactAuditRecord: 필드명 대신 정수 인덱스(CBOR map key) 사용 -> 평균 30% 절감 - 동일 세션 내 반복 데이터(session_id, vault_id 등) 참조 방식 적용 가능 - 페이로드 압축: CBOR 자체 압축 + 선택적 DEFLATE (NFC 대량 전송 시)
3. 배치 동기화 프로토콜 흐름¶
3.1. A. 정상 동기화 흐름¶
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ SE (Zone 3) │ │ 오프라인 앱 │ │ 대시보드 │
│ │ │ (Zone 2) │ │ (Zone 1) │
└──────┬──────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ 1. READ_AUDIT_DIGEST │
│◄──────────────────│ │
│ │ │
│ SEAuditDigest │ │
│ (128B) │ │
│──────────────────►│ │
│ │ │
│ │ 2. 축적 AuditRecord 수집
│ │ (마지막 동기화 이후)
│ │ │
│ │ 3. 배치 해시 계산 │
│ │ batch_hash = │
│ │ SHA-256(records) │
│ │ │
│ 4. UPDATE_AUDIT_DIGEST │
│ (latest_log_hash = batch_hash) │
│◄──────────────────│ │
│ │ │
│ 갱신된 SEAuditDigest │
│──────────────────►│ │
│ │ │
│ │ 5. AuditSyncPayload │
│ │ 조립 (se_digest + │
│ │ records + seq + │
│ │ prev_sync_hash) │
│ │ │
│ │ 6. sync_sig 서명 │
│ │ (오프라인 앱 키) │
│ │ │
│ │ 7. QR/NFC 전송 ──────►│
│ │ │
│ │ │ 8. 수신 검증:
│ │ │ a. sync_sig 검증
│ │ │ b. se_digest.digest_sig 검증
│ │ │ c. latest_log_hash == batch_hash 확인
│ │ │ d. sign_counter 연속성 확인
│ │ │ e. sequence 연속성 확인
│ │ │
│ │ │ 9. 레코드 저장
│ │ │ (3단계 아카이빙)
│ │ │
│ │ 10. ACK QR/NFC ◄─────│
│ │ │
│ │ 11. 로컬 동기화 │
│ │ 상태 업데이트 │
└──────────────────┘└─────────────────────┘
단계별 상세:
1. 오프라인 앱이 SE에서 READ_AUDIT_DIGEST로 현재 다이제스트 획득
2. 마지막 성공 동기화 이후 축적된 AuditRecord를 로컬 스토리지에서 수집
3. 수집된 레코드 전체의 SHA-256 해시(batch_hash) 계산
4. SE에 UPDATE_AUDIT_DIGEST로 latest_log_hash 갱신 요청 -> SE가 갱신 후 재서명
5. AuditSyncPayload 조립: 갱신된 se_digest + CompactAuditRecord 배열 + 시퀀스 + 이전 동기화 해시
6. 오프라인 앱 키로 전체 페이로드 서명 (sync_sig)
7. ur:dcent-audit-sync UR 타입으로 인코딩하여 QR 애니메이션 또는 NFC 전송
8. 대시보드 수신 후 5단계 검증 수행
9. 검증 통과 시 레코드를 글로벌 이벤트 스토어에 저장
10. ACK 응답을 QR/NFC로 반환
11. 오프라인 앱이 ACK 수신 후 동기화 상태 업데이트 (start_seq 갱신)
3.2. B. 긴급 동기화 흐름 (REG-US-04 대응)¶
SECURITY_EVENT 발생 시 72시간 이내 보고 의무를 충족하기 위한 즉시 동기화 프로토콜.
[트리거] SECURITY_EVENT 감지
(sec-intrusion-attempt, sec-tampering-detected,
sec-hash-chain-break, sec-counter-mismatch 등)
[즉시 조치]
1. SECURITY_EVENT AuditRecord 생성 (Zone 2)
2. SE에서 READ_AUDIT_DIGEST (현재 상태 스냅샷)
3. 소형 AuditSyncPayload 생성:
- sync_type: sync-emergency
- records: [SECURITY_EVENT 레코드만] (~200B)
- se_digest: 현재 스냅샷
4. QR 코드 1프레임으로 즉시 전송
[운영 절차 (SOP)]
- "보안 이벤트 감지 시 즉시 QR 스캔을 수행하시오"
- 오프라인 앱 UI: 긴급 동기화 배너 표시 + 경고음
- 대시보드: 긴급 이벤트 수신 시 관리자 즉시 알림 (이메일/SMS/Slack)
- 72시간 규제 보고 타이머 자동 시작 (REG-US-04)
긴급 동기화의 특징:
- 최소 데이터: 보안 이벤트 1-3개만 포함 (~200-500B)
- QR 1프레임으로 완료 가능 (4KB 미만)
- 나머지 축적 레코드는 후속 정상 동기화에서 전달
- payload_id로 긴급/정상 동기화 간 중복 방지
3.3. C. 대량 동기화 흐름¶
장기간 오프라인(예: 30일+) 후 축적 레코드가 QR 대역폭을 초과할 때의 처리.
[판단 기준]
축적 레코드 > 20개 OR 예상 크기 > 4KB -> 대량 동기화 진입
[분할 전송 프로토콜]
1. 축적 레코드를 N개 파트로 분할 (파트당 최대 20-30 레코드)
2. 각 파트에 대해 AuditSyncPayload 생성:
- sync_type: sync-partial
- sequence.part_index: 현재 파트 번호 (0-based)
- sequence.total_parts: 총 파트 수
- prev_sync_hash: 이전 파트의 해시 (첫 파트는 마지막 정상 동기화 해시)
3. 마지막 파트에서만 SE UPDATE_AUDIT_DIGEST 수행 (최종 batch_hash)
4. 전송 방식 선택:
a. QR 멀티파트: 각 파트를 순차 QR 전송 -> ACK -> 다음 파트
b. NFC 단일 세션: 32KB 이내면 NFC 1세션으로 전체 전달 (권장)
[대시보드 수신]
- 모든 파트 수신 후 전체 재조립
- 파트 간 해시 체인(prev_sync_hash) 연속성 확인
- 마지막 파트의 se_digest와 전체 레코드 해시 교차 검증
NFC 우선 권고 근거: - NFC 세션 대역폭(~32KB)은 QR v40(~4KB) 대비 8배 - 100개 레코드 * ~300B/레코드 = ~30KB -> NFC 1세션 가능 - 대량 동기화 시 "NFC 태그 접촉" UI 표시로 사용자 유도
4. 3계층 무결성 체인 설계¶
4.1. 아키텍처 개요¶
┌─────────────────────────────────────────────────────────────────┐
│ 3계층 무결성 체인 │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Layer 3: 대시보드 집계 (Zone 1) │ │
│ │ - 모든 Zone의 AuditRecord 통합 저장 │ │
│ │ - AuditSyncPayload 수신 검증 │ │
│ │ - 글로벌 이벤트 스토어 + 3단계 아카이빙 │ │
│ │ - OCSF/CEF/ESMA 변환 출력 (Phase 32) │ │
│ └────────────────────────────┬─────────────────────────────┘ │
│ │ AuditSyncPayload │
│ │ (QR/NFC) │
│ ┌────────────────────────────┴─────────────────────────────┐ │
│ │ Layer 2: 오프라인 앱 로그 체인 (Zone 2) │ │
│ │ - AuditRecord 해시 체인 (prev_hash 연결) │ │
│ │ - 로컬 서명 (오프라인 앱 키) │ │
│ │ - AuditSyncPayload 생성 + sync_sig 서명 │ │
│ │ - SEAuditDigest 스냅샷 포함 │ │
│ └────────────────────────────┬─────────────────────────────┘ │
│ │ APDU │
│ │ (물리적 연결) │
│ ┌────────────────────────────┴─────────────────────────────┐ │
│ │ Layer 1: SE 해시 앵커 (Zone 3) │ │
│ │ - SEAuditDigest (128B): latest_log_hash, sign_counter │ │
│ │ - 하드웨어 레벨 변조 방지 (EAL5+ NVM) │ │
│ │ - digest_sig로 자체 무결성 서명 │ │
│ │ - 최하위 신뢰 앵커 (Root of Trust) │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
4.2. Layer 1: SE 해시 앵커 (Root of Trust)¶
역할: 3계층 무결성 체인의 최하위 신뢰 앵커. 하드웨어 수준에서 변조가 불가능한 기준점.
구성 요소:
| 요소 | 내용 | 검증 대상 |
|------|------|----------|
| latest_log_hash | 마지막 동기화 로그 배치의 SHA-256 | Layer 2 해시 체인 일관성 |
| sign_counter | 단조 증가 서명 카운터 | 서명 횟수 연속성 |
| latest_sign_hash | 마지막 서명 트랜잭션 해시 | 서명 이력 일관성 |
| policy_hash | 현재 정책 해시 | 정책 상태 일관성 |
| digest_sig | SE 키로 서명한 다이제스트 | Layer 1 자체 무결성 |
공격 벡터 차단:
- SE NVM에 저장된 해시를 소프트웨어로 변조 불가 -> EAL5+ 물리적 보호
- digest_sig를 위조하려면 SE 개인키 필요 -> SE에서 추출 불가
- sign_counter를 감소시킬 수 없음 -> 단조 증가 하드웨어 로직
4.3. Layer 2: 오프라인 앱 로그 체인¶
역할: 에어갭 구간에서 발생하는 이벤트의 로컬 기록과 해시 체인 유지.
구성 요소:
| 요소 | 내용 | 검증 대상 |
|------|------|----------|
| AuditRecord 해시 체인 | prev_hash로 연결된 레코드 시퀀스 | 레코드 연속성, 삽입/삭제 탐지 |
| 로컬 서명 | 각 레코드에 오프라인 앱 키 서명 | 레코드 생성자 진위 |
| AuditSyncPayload | 배치 전달 단위 | 동기화 완전성 |
| prev_sync_hash | 동기화 배치 간 해시 체인 | 배치 연속성 |
해시 체인 검증:
레코드 체인 검증:
for i in 1..N:
assert records[i].prev_hash == SHA-256(CBOR(records[i-1]))
배치 체인 검증:
assert current_payload.prev_sync_hash == SHA-256(CBOR(prev_payload))
4.4. Layer 3: 대시보드 집계¶
역할: 모든 Zone의 감사 레코드를 통합 관리하고, 규제 보고서의 원본 데이터를 제공.
구성 요소: | 요소 | 내용 | 검증 대상 | |------|------|----------| | 글로벌 이벤트 스토어 | 모든 Zone의 AuditRecord 통합 DB | 완전성, 일관성 | | AuditSyncPayload 검증 | 수신 페이로드의 5단계 검증 | Layer 2 -> 3 전이 무결성 | | SEAuditDigest 대조 | SE 앵커와 수신 데이터 비교 | Layer 1 -> 3 앵커 일치 | | 3단계 아카이빙 | 활성/아카이브/영구 보존 | 장기 데이터 무결성 |
4.5. 계층 간 교차 검증 매트릭스¶
| 검증 항목 | Layer 1 -> Layer 2 | Layer 2 -> Layer 3 | Layer 1 -> Layer 3 |
|---|---|---|---|
| 해시 앵커 | SE latest_log_hash = 앱 배치 해시 |
앱 sync_sig 검증 |
SE latest_log_hash = 대시보드 수신 해시 |
| 카운터 연속 | SE sign_counter = 앱 기록 서명 횟수 누적 |
앱 sequence (start_seq/end_seq) 연속 |
SE sign_counter = 대시보드 누적 TX_SIGN 수 |
| 시간 정합 | SE timestamp ~ 앱 레코드 timestamp (허용: 수 초) |
앱 레코드 timestamp ~ 수신 시간 (허용: 24시간) | SE timestamp ~ 대시보드 기록 시간 (허용: 24시간) |
| 서명 검증 | SE digest_sig (SE audit_key 공개키) |
앱 sync_sig (앱 공개키) |
SE digest_sig (SE audit_key 공개키) |
| 정책 일치 | SE policy_hash = 앱 로컬 정책 해시 |
앱 전달 정책 이벤트 일관성 | SE policy_hash = 대시보드 정책 해시 |
4.6. 교차 검증 실행 알고리즘¶
대시보드가 AuditSyncPayload 수신 시 실행하는 검증 절차:
Step 1: 서명 검증 (즉시)
a. sync_sig 검증 (오프라인 앱 공개키)
b. se_digest.digest_sig 검증 (SE audit_key 공개키)
c. 어느 하나라도 실패 -> REJECT + SECURITY_EVENT(sec-tampering-detected)
Step 2: 해시 앵커 검증
a. batch_hash = SHA-256(CBOR(payload.records))
b. assert se_digest.latest_log_hash == batch_hash
c. 불일치 -> SECURITY_EVENT(sec-hash-chain-break) + 관리자 알림
Step 3: 시퀀스 연속성 검증
a. 이전 동기화의 end_seq + 1 == 현재 start_seq
b. 갭 존재 시 -> GapRange 기록 + "갭 존재" 주석
c. 레코드 내부 해시 체인(prev_hash) 연속성 확인
Step 4: 카운터 연속성 검증
a. 이전 동기화의 se_digest.sign_counter <= 현재 sign_counter
b. 증분 = TX_SIGN 레코드 수와 일치 확인
c. 불일치 -> SECURITY_EVENT(sec-counter-mismatch)
Step 5: 시간 정합성 검증
a. |se_digest.timestamp - 수신시간| < 24시간
b. 레코드 timestamp가 시간순 정렬되어 있는지 확인
c. 범위 초과 -> 경고 플래그 (동기화 지연 주석)
모든 Step 통과 -> 레코드 저장 + SYNC_COMPLETE 이벤트 생성
5. 동기화 실패 시나리오별 복구 절차¶
5.1. A. QR 스캔 타임아웃¶
증상: QR 애니메이션 프레임 누락으로 대시보드가 불완전한 데이터를 수신했거나, 스캔 자체가 실패하여 데이터가 도달하지 않은 상태.
복구 절차:
1. 대시보드: "스캔 실패" 표시 + 재시도 안내
2. 오프라인 앱: 동일 AuditSyncPayload 유지 (삭제하지 않음)
3. 재전송: 동일 payload_id로 재전송
4. 대시보드: payload_id 중복 감지 -> idempotent 처리
- 이미 저장된 경우: ACK 반환 (중복 무시)
- 미저장 상태: 정상 검증 후 저장
5. 3회 실패 시: NFC 채널로 전환 권고
5.2. B. 부분 전송 (분할 페이로드)¶
증상: N개 파트 중 일부만 대시보드에 도달 (분할 동기화 중 중단).
복구 절차:
1. 대시보드: 수신 파트 목록 확인
- 예: 파트 0, 1, 3 수신 (파트 2 누락)
2. 대시보드 -> 오프라인 앱: 누락 파트 번호 ACK QR에 포함
- ACK 포맷: { status: "partial", missing_parts: [2] }
3. 오프라인 앱: 누락 파트만 재생성 + 재전송
4. 대시보드: 모든 파트 수신 후 재조립
5. 전체 해시 체인 검증 수행
5.3. C. 시퀀스 갭¶
증상: 현재 페이로드의 start_seq이 이전 end_seq + 1이 아닌 경우. 중간 동기화가 누락된 상태.
복구 절차:
1. 대시보드: 갭 범위 계산
- expected_start = 이전 end_seq + 1
- expected_end = 현재 start_seq - 1
- 갭 크기 = expected_end - expected_start + 1
2. Case A: 갭 복구 가능 (오프라인 앱에 데이터 존재)
a. 대시보드 -> 오프라인 앱: 갭 범위 요청 ACK
{ status: "gap", gap_range: { start: N, end: M } }
b. 오프라인 앱: 해당 범위 레코드 수집 -> 보충 AuditSyncPayload 생성
c. 보충 페이로드 전송 -> 대시보드 수신 -> 갭 채움
d. 전체 시퀀스 연속성 재확인
3. Case B: 갭 복구 불가 (오프라인 앱 데이터 손실)
a. 갭 불가 복구 마킹: "IRRECOVERABLE_GAP" 상태
b. SE 해시 앵커로 보증:
- "갭 구간 이전 + 이후 해시 체인은 SE 앵커로 검증됨"
- 갭 자체는 손실이나, 갭 전후의 무결성은 보존
c. SECURITY_EVENT(sec-hash-chain-break) 기록
d. 감사 보고서에 "동기화 갭 존재" 주석 자동 포함
e. 관리자 알림: "데이터 손실 구간 발생, 수동 확인 필요"
5.4. D. SE 다이제스트 불일치¶
증상: AuditSyncPayload에 포함된 se_digest.latest_log_hash와 수신 레코드 배치의 SHA-256 해시가 일치하지 않는 경우.
원인 추정 및 복구:
1. 원인 1: 오프라인 앱 변조
- 앱이 레코드를 변조 후 AuditSyncPayload에 포함
- 그러나 SE의 latest_log_hash는 변조 전 해시
-> 탐지: 해시 불일치 즉시 감지
-> 조치: SECURITY_EVENT(sec-tampering-detected)
해당 페이로드 격리 + 관리자 긴급 알림
2. 원인 2: 중간 레코드 누락
- 오프라인 앱이 일부 레코드를 누락하고 페이로드 생성
- SE에 제출한 batch_hash와 실제 전송 레코드 해시 불일치
-> 탐지: 레코드 수 검증 (sign_counter 증분과 비교)
-> 조치: 누락 레코드 보충 요청
3. 원인 3: SE 다이제스트 미갱신
- 오프라인 앱이 UPDATE_AUDIT_DIGEST를 호출하지 않은 상태로 전송
- SE의 latest_log_hash가 이전 배치의 해시
-> 탐지: se_digest.timestamp < 페이로드 생성 시간
-> 조치: 오프라인 앱에 SE 다이제스트 갱신 후 재전송 요청
4. 공통 조치:
- 불일치 이벤트를 SECURITY_EVENT로 기록
- 관리자 알림 (severity: high 이상)
- 수동 검증 절차 시작 (감사인 또는 보안 담당자)
5.5. E. 장기 미동기화 (30일+)¶
증상: 대시보드에 특정 기기로부터 30일 이상 동기화 수신이 없는 상태.
대응:
[경고 단계]
- 7일 미동기화: 대시보드에 "동기화 지연" 경고 (severity: low)
- 14일 미동기화: 관리자 이메일 알림 (severity: medium)
- 30일 미동기화: 긴급 알림 + 감사 보고서 "불완전" 마킹 (severity: high)
[위험 요소]
- 감사 증적 연속성 훼손: 해당 기기의 이벤트가 규제 보고서에 누락
- 규제 위반 위험: 보존 의무 기간 내 증적 부재
- 보안 사각지대: 해당 기기에서 발생한 보안 이벤트 미보고
[복구 절차]
1. 관리자가 해당 기기를 물리적으로 확인
2. 오프라인 앱 상태 점검 (데이터 축적량 확인)
3. NFC 대량 동기화 수행 (축적 데이터가 클 것으로 예상)
4. 동기화 완료 후 sign_counter 연속성 확인
5. 감사 보고서에 "동기화 지연 기간: X일, 이후 복구 완료" 주석 자동 포함
[예방]
- 동기화 주기 SOP 설정 (권장: 일 1회 이상)
- 오프라인 앱에 "마지막 동기화 N일 전" 배너 상시 표시
- 동기화 리마인더 알림 (앱 푸시, 대시보드 경고)
6. 감사인 검증 시나리오¶
6.1. 표준 감사 검증 절차¶
외부 감사인이 임의 시점의 감사 증적 무결성을 검증하는 절차.
[사전 준비]
- 감사인에게 Auditor 역할 부여 (RBAC v2)
- 대시보드에서 "감사 모드" 활성화
- 검증 대상 기간 결정 (예: 2026-01-01 ~ 2026-03-31)
[Step 1: SE 현재 상태 스냅샷]
1. 감사 대상 SE 기기에서 READ_AUDIT_DIGEST
2. SEAuditDigest 128B 획득
3. digest_sig 검증 (SE audit_key 공개키)
[Step 2: 대시보드 기록 조회]
1. 검증 대상 기간의 AuditRecord 조회
2. 해당 기간의 AuditSyncPayload 이력 조회
3. 각 동기화의 se_digest 스냅샷 조회
[Step 3: 해시 체인 구간 검증]
1. 대상 기간의 첫 번째 레코드부터 마지막까지 순회
2. 각 레코드의 prev_hash == SHA-256(이전 레코드) 확인
3. 마지막 레코드의 해시 -> 해당 시점의 AuditSyncPayload 배치 해시와 대조
[Step 4: SE 앵커 교차 검증]
1. 현재 SE latest_log_hash == 대시보드의 마지막 동기화 배치 해시
2. SE sign_counter >= 대시보드 누적 TX_SIGN 레코드 수
3. SE policy_hash == 대시보드의 현재 정책 해시
[Step 5: 결과 보고]
- 모든 검증 통과: "감사 대상 기간 증적 무결성 확인됨"
- 부분 실패: "구간 X~Y 해시 체인 불일치, 나머지 구간 무결"
- 전체 실패: "SE 앵커 불일치, 전체 증적 신뢰 불가"
6.2. 감사 검증 보고서 자동 생성¶
대시보드는 감사인의 요청에 따라 검증 결과를 자동으로 보고서 형태로 생성한다: - 검증 대상 기간 - 총 레코드 수, Zone별 분포 - 해시 체인 검증 결과 (통과/실패 구간) - SE 앵커 교차 검증 결과 - 동기화 갭 여부 및 복구 이력 - 보안 이벤트 요약
이 보고서의 상세 포맷과 규제별 출력 변환은 Phase 32에서 설계한다.
Phase: 30-audit-architecture Version: 1.0 UR 타입: ur:dcent-audit-sync (Phase 27 패턴 준수)
관련 문서¶
- 감사 로그 레코드 CDDL 스키마 설계 -- 규제 준수
- Proof of Cold Storage 보고서 구조 및 SE 서명 자동 증명 설계 -- 규제 준수
- SEAuditDigest CBOR 스키마 및 SE 역할 경계 정의 -- 규제 준수