시스템 설계: BLE+UWB 차량 디지털 키
“BLE+UWB 기반 차량 디지털 키 시스템을 설계하세요”라는 시스템 설계 문제에 대한 접근법을 정리한다. CCC Digital Key Release 3.0 표준 구조를 기반으로 한다.
요구사항 정리
면접에서 먼저 확인해야 할 것들이다.
기능 요구사항:
- 스마트폰을 꺼내지 않고 차량에 접근하면 자동 잠금해제 (패시브 엔트리)
- 거리에 따라 다른 동작 (웰컴 라이트 → 잠금해제 → 시동 활성화)
- 소유자가 다른 사람에게 키를 공유/취소할 수 있다
- 폰 배터리가 죽어도 NFC로 잠금해제 가능
비기능 요구사항:
- 릴레이 어택 방어 (공격자가 중계 장비로 신호를 전달해 원격 잠금해제하는 것 차단)
- 응답 시간: 사용자가 문 앞에 도착했을 때 지연 없이 잠금해제 (< 500ms)
- iOS / Android 모두 지원
- 키 데이터는 하드웨어 보안 영역에 격리
컴포넌트 아키텍처
┌─────────────────────────────────────────────────┐
│ 스마트폰 │
│ ┌──────────┐ ┌─────┐ ┌─────┐ ┌───────────┐ │
│ │Secure │ │BLE │ │UWB │ │NFC │ │
│ │Element │ │Radio│ │Radio│ │(패시브 가능)│ │
│ └────┬─────┘ └──┬──┘ └──┬──┘ └─────┬─────┘ │
└───────┼───────────┼────────┼────────────┼───────┘
│ │ │ │
│ ┌─────┼────────┼────────────┼──────┐
│ │ ▼ ▼ ▼ │
│ │ ┌─────┐ ┌──────┐ ┌────────┐ │
│ │ │BLE │ │UWB │ │NFC │ │
│ │ │모듈 │ │앵커x4│ │리더 │ │
│ │ └──┬──┘ └──┬───┘ └───┬────┘ │
│ │ │ │ │ │
│ │ ▼ ▼ ▼ │
│ │ ┌──────────────────────────┐ │
│ │ │ Digital Key ECU │ │
│ │ │ (Zone Controller) │ │
│ │ │ + 차량측 Secure Element │ │
│ │ └────────────┬─────────────┘ │
│ │ │ CAN / Ethernet │
│ │ ▼ │
│ │ ┌──────────────────────────┐ │
│ │ │ Body Control Module │ │
│ │ │ - 문 잠금/해제 │ │
│ │ │ - 웰컴 라이트 │ │
│ │ │ - 이모빌라이저 │ │
│ │ │ - 시트/미러 프리셋 │ │
│ │ └──────────────────────────┘ │
│ │ 차량 │
│ └──────────────────────────────────┘
│
▼
┌────────────────────────┐
│ 완성차 제조사 서버 │
│ (BMW, 현대 등) │
│ - 키 프로비저닝 │
│ - 키 취소 │
│ - OTA 업데이트 │
└────────────────────────┘
핵심 컴포넌트:
- 폰 SE (Secure Element): ECC 키 쌍 생성·저장. 개인키는 SE 밖으로 나오지 않는다
- 차량 SE: 동일 역할. 인증 시 챌린지에 서명
- BLE 모듈: 접근 감지 + 인증 채널
- UWB 앵커: 정밀 위치 측정 (최소 3개, 권장 4개)
- NFC 리더: 배터리 백업용 물리 태그 인터페이스
- Digital Key ECU: 인증 로직 + 존 판정 + 액션 디스패치
전체 동작 흐름
사용자가 폰을 주머니에 넣은 채로 차에 다가가면 자동으로 잠금이 해제되는 전체 과정이다.
① BLE 감지 (1030m)
차량의 BLE 모듈이 1~2초 간격으로 광고 패킷을 송출한다. 시동이 꺼진 상태에서도 12V 배터리로 상시 구동된다. 소비 전류 수십 µA 수준으로, 기존 키 포브의 LF 수신기가 항상 켜져 있는 것과 같다.
광고 주소와 프라이버시: 차량의 고유 ID를 평문으로 광고하면 제3자가 차량을 추적할 수 있다. 그래서 BLE의 **RPA (Resolvable Private Address)**를 사용한다. (상세: BLE IRK와 Resolvable Private Address)
- 최초 등록 시 차량과 폰이 IRK (Identity Resolving Key)를 교환한다
- 차량은 IRK로 생성한 RPA를 광고 주소로 사용한다. ~15분마다 주소가 바뀐다
- 등록된 폰만 자기가 가진 IRK로 RPA를 역산해 “내 차”임을 식별한다
- IRK가 없는 제3자에게는 매번 다른 랜덤 주소로 보인다
폰이 자기 차량의 광고를 식별하면 BLE 연결을 수립한다. 이 시점에서는 “등록된 폰 중 하나가 가까이 왔다” 정도만 알 수 있다. 정확히 어디에 있는지는 모른다.
② BLE 상호 인증
BLE 연결이 되면 양쪽이 서로를 인증한다.
차량 ECU 폰 SE
│ │
│── 랜덤 챌린지 (nonce) ────────────▶│
│ │ SE 개인키로 서명
│◀── 서명 + 폰 인증서 체인 ──────────│
│ 폰 공개키로 서명 검증 │
│ │
│ (역방향도 동일하게 수행) │
│── 차량 서명 + 차량 인증서 체인 ────▶│
│ │ 차량 공개키로 서명 검증
│ │
│ 상호 인증 완료 │
- 왜 상호 인증인가: 차량도 자신이 정당한 차량임을 증명해야 한다. 공격자가 가짜 BLE 광고를 띄워 폰의 키 데이터를 빼내는 것을 방지한다
- 챌린지가 매번 랜덤인 이유: 이전 응답을 녹음해서 재전송하는 리플레이 어택을 막는다
- ECC P-256: RSA 대비 키 크기가 작고 (256bit vs 2048bit), SE의 제한된 연산 능력에 적합하다
- 인증서 체인은 최초 등록(프로비저닝) 시 교환해 둔 것이다
③ 세션키 유도
인증이 끝나면 양쪽 SE가 ECDH (Elliptic Curve Diffie-Hellman)로 공유 비밀을 생성하고, 여기서 UWB 레인징용 세션키를 유도한다.
- 매 연결마다 새 세션키가 생성된다. 이전 세션의 키는 재사용되지 않는다
- 세션키의 최대 유효 시간은 12시간. 초과하면 BLE 재인증이 필요하다
- 이 세션키가 UWB 패킷의 STS (Scrambled Timestamp Sequence) 암호화에 사용된다
④ UWB 레인징 시작
BLE 인증이 끝난 후에만 UWB 앵커를 활성화한다. UWB는 BLE보다 전력 소모가 크기 때문에 인증 전에 켜면 낭비다. 인증 없이 레인징을 시작하면 아무 폰이나 차량의 UWB 세션을 트리거할 수도 있다.
DS-TWR (Double-Sided Two-Way Ranging) 과정:
폰 UWB 앵커
│── poll ──────────────────────▶│
│ │ 수신 시각 기록
│◀─────────────────── respond ──│
│ 수신 시각 기록 │
│── final poll ────────────────▶│
│ │
│ 양쪽이 독립적으로 ToF 계산 │
│ → 거리 = (비행 시간 × 광속) / 2│
- 3패킷 교환(poll → respond → final poll)으로 양쪽 시계 오차를 상쇄한다
- 각 앵커가 독립적으로 폰까지의 거리를 측정한다
- 레인징 주기: 10Hz (100ms 간격). 한 사이클이 ~2ms이므로 4개 앵커 순회에 ~10ms
- 모든 패킷에 STS가 포함된다. 세션키를 모르면 패킷을 위조하거나 도청할 수 없다
⑤ 위치 계산 + 존 판정
4개 앵커의 거리 데이터를 ECU가 수집해 삼변측량(multilateration)으로 폰의 3D 위치를 계산한다.
A1(좌측 미러) ──── 2.3m ────┐
A2(우측 미러) ──── 4.1m ────┤
A3(실내 중앙) ──── 3.8m ────┼──▶ ECU: 위치 = 운전석 문 앞 1.2m
A4(트렁크) ──── 5.2m ────┘
위치에 따라 존을 판정하고 대응하는 액션을 실행한다.
| 존 | 거리 | 액션 | 트리거 조건 |
|---|---|---|---|
| Welcome | 5~10m | 웰컴 라이트, 공조 사전 작동 | UWB 최초 위치 확인 |
| Unlock | ~1.5m (문 근처) | 해당 문 잠금 해제, 시트/미러 프리셋 로드 | 문 방향으로 접근 확인 |
| Cabin | 실내 | 시동 버튼 활성화 | 실내 앵커 거리가 차체 크기 이내 |
- 방향 인식: 운전석 쪽으로 접근하면 운전석 문만, 트렁크 쪽이면 트렁크만 열린다
- 다중 사용자: 폰마다 별도 UWB 세션이므로 두 명이 동시에 접근해도 각각의 문을 따로 열 수 있다
⑥ Walk-Away 잠금
사용자가 차에서 멀어지면 역순으로 잠금한다.
- Cabin → Unlock 이탈: 시동 버튼 비활성화
- Unlock → Welcome 이탈: 문 잠금 + 미러 접힘
- Welcome 이탈: 라이트 OFF, UWB 세션 종료, BLE 연결 해제
전체 시퀀스 요약
폰 (주머니) 차량 BLE Digital Key ECU UWB 앵커 x4 Body Control
│ │ BLE 광고 중 │ │ │
│── ① BLE 스캔 응답 ▶│ │ │ │
│ │── 디바이스 감지 ──▶│ │ │
│◀── ② 랜덤 챌린지 ────────────────│ │ │
│── ② 챌린지에 SE 개인키로 서명 ──▶│ │ │
│ │ │ ③ 공개키로 검증 │ │
│ │ │ + 세션키 유도 │ │
│ │ │── ④ UWB 시작 ───▶│ │
│ │ │ (STS 키 배포) │ │
│◀───────── ④ TWR 레인징 (10Hz) ────│ │ │
│ │ │◀─ 거리/각도 데이터 ─│ │
│ │ │ ⑤ 존 판정 │ │
│ │ │ │ │
│ │ │ [Welcome 5~10m] ─────── 웰컴 라이트 ON
│ │ │ [Unlock 1~2m] ─────── 문 잠금 해제
│ │ │ ─────── 시트/미러 프리셋
│ │ │ [Cabin 실내] ─────── 시동 버튼 활성화
│ │ │ │ │
│ ⑥ 사용자가 멀어지면 역순으로 잠금 │ │
UWB 앵커 배치와 존 판정
앵커 토폴로지
┌─────────────────────┐
│ 차량 상면 │
[A1] │ │ [A2]
(좌측 │ │ 우측
사이드 │ │ 사이드
미러) │ │ 미러)
│ │
│ [A3] │
│ (실내 중앙) │
│ │
[A4] │ │
(트렁크│ │
근처) └─────────────────────┘
- 최소 3개: 2D 삼변측량 가능. 하지만 앞/뒤 구분이 약하다
- 권장 4개: 3D 위치 추정. 문 근처와 실내 구분 정확도 상승
- 각 앵커는 DS-TWR (Double-Sided Two-Way Ranging) 로 거리 측정. ToF + AoA 병행하면 앵커 수를 줄일 수 있다
존 판정 로직
function determineZone(distances[4], angles[4]):
position = multilaterate(distances, angles, anchorPositions)
if isInsideCabin(position):
return CABIN
distToNearestDoor = minDoorDistance(position)
if distToNearestDoor < 1.5m:
return UNLOCK
if euclideanDistance(position, vehicleCenter) < 10m:
return WELCOME
return OUT_OF_RANGE
isInsideCabin(): 차량 외곽 경계 폴리곤 내부에 있는지 판정. 앵커 3개 이상의 거리가 모두 차체 크기 이내일 때- 판정 주기: 10Hz (100ms 간격). UWB TWR 한 사이클이 ~2ms이므로 4개 앵커 순회에 ~10ms
- 히스테리시스: 존 경계에서 진동 방지. Unlock→Welcome 전환은 2m (진입은 1.5m). 최소 3회 연속 동일 존이어야 전환
폴백 설계
잠금해제 수단이 단계적으로 degradation되는 구조다.
정상 폰 배터리 소진 차량 12V 방전
BLE+UWB ──────▶ NFC 태그 ──────▶ 물리 키 (기계식)
(패시브 엔트리) (Power Reserve) (문 손잡이 키 실린더)
폰 배터리 소진 시: NFC 폴백
┌─────────────────────────────────┐
│ iPhone Power Reserve Mode │
│ - 배터리 0% 후 최대 5시간 동작 │
│ - BLE/UWB 불가. NFC만 가능 │
│ - SE는 NFC 필드에서 에너지 수확 │
│ (자체 전원 불필요) │
└─────────────────────────────────┘
동작 흐름:
- 사용자가 폰을 NFC 리더 (보통 문 손잡이 또는 B필러)에 태그
- NFC 필드가 SE에 전력 공급 → SE가 활성화
- 차량이 Fast Transaction 실행: 챌린지 → SE 서명 → 검증 → 잠금해제
- 전체 과정 < 500ms (NFC 필드 내에서 완결)
설계 시 고려사항:
| 항목 | 결정 |
|---|---|
| NFC 리더 위치 | 문 손잡이 또는 B필러. 직관적으로 태그할 수 있는 곳 |
| 트랜잭션 타입 | Fast Transaction (대칭키 기반, 단방향 인증) |
| 시동 | NFC 태그로 시동도 가능하게 할 것인가? → 별도 NFC 리더를 센터콘솔에 배치 |
| Android 폰 | Power Reserve 미지원 기기가 많다. 완전 방전 시 NFC 불가 → 물리 키 백업 필요 |
차량 12V 방전 시: 물리 키
차량 배터리가 방전되면 BLE, UWB, NFC 리더 모두 전원이 없어 동작하지 않는다.
- 운전석 문 손잡이에 물리 키 실린더가 있다. 커버 뒤에 숨겨져 있는 경우가 많다
- 디지털 키 전용 차량도 이 실린더는 제거하지 않는다. 법규상 기계식 잠금해제 수단이 요구되는 시장이 있다
- 시동은 점프 스타트 후 디지털 키로 건다. 물리 키로 문만 열 수 있고 시동은 걸 수 없는 구조가 일반적이다
릴레이 어택 방어
공격 시나리오
폰 (집 안) ←───릴레이 A───→ ←───릴레이 B───→ 차량 (주차장)
BLE 신호 중계 BLE 신호 중계
공격자 2명이 중계 장비로 BLE 신호를 양방향 전달한다. 차량은 폰이 바로 옆에 있다고 판단한다.
BLE만으로는 불가능한 이유
BLE는 RSSI (신호 세기)로 거리를 추정한다. 중계 장비가 신호를 증폭하면 RSSI가 정상으로 보인다. 오차도 1~5m이라 정밀 판별이 불가능하다.
UWB ToF가 막는 원리
| 정상 (1m) | 릴레이 경유 (실제 50m) | |
|---|---|---|
| 전파 비행 시간 | 3.3ns | 166ns+ (중계 지연 추가) |
| UWB 측정 거리 | 1.0m | 50m+ |
| 판정 | Unlock Zone | OUT_OF_RANGE |
- 빛의 속도는 속일 수 없다. 어떤 중계 장치라도 처리 지연(최소 수백 ns)을 추가한다
- UWB ToF는 10~30cm 정밀도로 이 지연을 감지한다
- IEEE 802.15.4z STS (Scrambled Timestamp Sequence): AES-128 기반 의사난수 시퀀스를 레인징 패킷에 포함. 키를 모르면 패킷을 위조하거나 재생할 수 없다
추가 공격 벡터와 대응
| 공격 | 설명 | 대응 |
|---|---|---|
| 릴레이 어택 | 신호 중계로 거리 속이기 | UWB ToF로 실제 거리 검증 |
| 리플레이 어택 | 이전 레인징 패킷 재전송 | STS의 세션별 키 + 카운터. 동일 패킷 재사용 불가 |
| 재밍 | UWB 대역 전파 방해 | 레인징 실패 시 잠금해제 거부 (fail-secure). NFC 폴백 안내 |
| 디프닝 어택 | 예측 가능한 응답 타이밍에 악성 패킷 주입 | 응답 타이밍에 랜덤 지연 추가 |
fail-secure 원칙: UWB 측정이 실패하거나 비정상이면 잠금해제를 거부한다. 편의성보다 보안이 우선이다.
폰 플랫폼별 전략
iOS와 Android는 디지털 키 지원 수준이 다르다. 설계 시 양쪽의 제약을 모두 수용해야 한다.
기능 비교
| 기능 | iOS (iPhone 11+) | Android (Pixel 6+, Galaxy S21+) |
|---|---|---|
| UWB 칩 | U1/U2 (전 기종 동일) | 기기별 상이. 미탑재 기기 존재 |
| SE | Apple SE (전용 하드웨어) | StrongBox SE 또는 TEE 폴백 |
| NFC Power Reserve | 지원 (배터리 0% 후 5시간) | 대부분 미지원 |
| BLE 백그라운드 | Core Bluetooth로 안정적 | Doze 모드에서 스캔 제한 |
| CCC 지원 | Wallet 통합 (네이티브) | Google Wallet 통합 |
플랫폼별 설계 분기
function selectProtocol(device):
if device.hasUWB and device.hasSE:
// 풀 스펙: BLE + UWB 패시브 엔트리
return PASSIVE_ENTRY_UWB
if device.hasBLE and device.hasSE:
// UWB 미탑재: BLE only 패시브 엔트리
// 릴레이 방어 약함 → BLE Channel Sounding 적용 검토
return PASSIVE_ENTRY_BLE_ONLY
// 최소 사양: NFC 탭 방식
return NFC_TAP_ONLY
안드로이드 특이사항
- Doze 모드: 화면 꺼진 후 일정 시간이 지나면 BLE 스캔 주기가 수 분 단위로 느려진다. Foreground Service + 알림으로 우회하거나, Companion Device Manager API를 사용해 BLE 스캔 예외를 받아야 한다
- UWB 파편화: 같은 칩셋(NXP SR100T)이라도 제조사마다 펌웨어 버전과 API 노출 수준이 다르다. FiRa UCI 표준 API를 사용해 추상화한다
- SE 부재: 중저가 기기에는 StrongBox SE가 없다. TEE (Trusted Execution Environment)로 폴백하면 side-channel 공격에 더 취약하다. 이 경우 키 유효 기간을 짧게 (24시간) 설정하고 서버 갱신을 요구하는 식으로 보완한다
iOS 특이사항
- Express Mode: Face ID / 패스코드 없이 NFC + BLE 키가 동작한다. Fast Transaction (대칭키 기반 단방향 인증)을 사용한다
- Background BLE: Core Bluetooth가 백그라운드에서도 안정적으로 BLE 광고를 수신한다. Android보다 패시브 엔트리 반응 속도가 빠르다
- Power Reserve: 배터리 0% 후에도 NFC 트랜잭션이 가능하다. SE가 NFC 필드에서 에너지를 수확해 자체 구동한다
CCC Release 3.0 구조 요약
면접에서 “표준이 있나요?”라는 질문에 답할 수 있으면 차별화된다.
| 항목 | 내용 |
|---|---|
| 표준 | CCC (Car Connectivity Consortium) Digital Key Release 3.0 |
| 참여사 | Apple, Google, Samsung, BMW, Hyundai, Mercedes 등 |
| 라디오 | NFC + BLE + UWB (세 가지를 함께 사용) |
| 인증서 구조 | 디바이스 Instance CA + 차량 제조사 CA. 공개키만 교환 |
| 프로비저닝 | SPAKE2+ (패스워드 기반 키 교환) → SCP03 보안 채널 → SE에서 키 생성 |
| 레인징 보안 | IEEE 802.15.4z HRP UWB + STS (AES-128 기반) |
| 키 공유 | 소유자 SE가 상대방 공개키에 서명 → 차량이 서명 검증 후 수락 |
| 프라이버시 | 디바이스 식별자 암호화 전송. Apple/Google 서버는 사용 시점·위치를 알 수 없다 |
Release 4.0 (2025): iOS ↔ Android 크로스 플랫폼 키 공유 표준화.
면접에서 다룰 수 있는 추가 토픽
- 다중 사용자: 운전석 쪽 문에 접근하는 키를 식별해 해당 사용자의 시트/미러 프리셋을 로드. UWB 위치 추적으로 어느 문 쪽인지 판별
- 렌터카 / 카셰어링: 시간 제한이 있는 키를 서버에서 발급. 유효 기간이 지나면 SE에서 자동 만료
- OTA 업데이트: 차량 측 Digital Key 서비스를 소프트웨어로 분리해 하드웨어 교체 없이 프로토콜 업그레이드
- Bluetooth 6.0 Channel Sounding: BLE만으로 10cm 정밀도를 달성할 수 있다는 스펙이나, 멀티패스 환경에서는 UWB보다 열위. UWB 미탑재 기기의 보완책으로 논의 가능
메모
- BLE 인증이 끝나기 전에 UWB를 켜지 않는다. 인증 없이 레인징하면 아무 폰이나 차량의 UWB 세션을 트리거할 수 있다
- 존 판정에 히스테리시스가 없으면 경계에서 문이 반복 잠금/해제된다. 진입 임계값과 이탈 임계값을 분리해야 한다
- NFC 폴백은 반드시 설계에 포함한다. “배터리 죽으면 어떡하죠?”는 면접에서 거의 반드시 나오는 질문이다
- UWB 재밍 시 잠금해제를 허용하면 안 된다 (fail-secure). 편의성 우선으로 설계하면 보안 구멍이 된다
- 안드로이드 Doze 모드를 고려하지 않으면 “주머니에 넣은 상태에서 패시브 엔트리가 안 돼요”라는 문제가 발생한다