BLE IRK와 Resolvable Private Address

BLEIoT

BLE 디바이스가 광고할 때 고정된 주소를 사용하면 제3자가 디바이스를 추적할 수 있다. IRK (Identity Resolving Key)와 RPA (Resolvable Private Address)는 주소를 주기적으로 바꾸면서도 신뢰된 기기만 상대를 식별할 수 있게 하는 메커니즘이다.

BLE 주소 체계

BLE 주소는 48비트(6바이트)이다. 크게 네 가지 유형이 있다.

유형상위 2비트변경 여부식별 가능
Public Address-고정 (IEEE 등록)누구나
Random Static Address11부팅 시 변경 가능, 런타임 중 고정누구나 (해당 세션 내)
Random Private Non-Resolvable00주기적 변경아무도 못함
Random Private Resolvable (RPA)01주기적 변경IRK 보유자만
  • Public Address: IEEE에 등록하는 고유 주소. MAC 주소와 동일한 방식. 항상 고정이므로 추적에 취약하다
  • Random Static: IEEE 등록 없이 사용. 부팅마다 바꿀 수 있지만 런타임 중에는 고정이다
  • Non-Resolvable: 주기적으로 바뀌지만 누구도 이전 주소와 연결할 수 없다. 본딩(재연결)이 필요 없는 비콘 등에 사용한다
  • Resolvable (RPA): 주기적으로 바뀌지만, IRK를 가진 기기만 “이전과 같은 디바이스다”를 알 수 있다

디지털 키, 웨어러블, 이어폰 등 본딩 후 재연결이 필요한 디바이스는 RPA를 사용한다.

IRK (Identity Resolving Key)

IRK는 128비트 대칭키다. 디바이스가 로컬에서 랜덤 생성하거나 제조 시 할당한다.

교환 시점: 두 디바이스가 본딩(bonding)할 때 SMP (Security Manager Protocol)를 통해 IRK를 교환한다. 각 디바이스는 상대의 IRK를 Resolving List에 저장한다.

디바이스 A                     디바이스 B
   │                              │
   │── 페어링 + 본딩 ────────────▶│
   │                              │
   │◀── IRK_B 전달 ──────────────│
   │── IRK_A 전달 ──────────────▶│
   │                              │
   │ Resolving List:              │ Resolving List:
   │   IRK_B → B의 Identity Addr  │   IRK_A → A의 Identity Addr
  • IRK는 본딩 시 한 번 교환되면 이후 변경되지 않는다
  • 디바이스를 초기화(factory reset)하면 IRK가 삭제되고 새로 생성된다. 이전에 본딩된 기기는 더 이상 주소를 해석할 수 없다

RPA 구조

RPA는 48비트이며 두 부분으로 구성된다.

MSB                                          LSB
┌──────────────── 48비트 ────────────────────┐
│  prand (24비트)     │     hash (24비트)     │
│  [01xxxxxx xxxxxxxx xxxxxxxx]  [hh hh hh]  │
└─────────────────────┴──────────────────────┘
      ↑ 상위 2비트는 01 고정 (RPA 식별자)
  • prand: 22비트 랜덤값 + 상위 2비트 01 고정. RPA임을 나타내는 마커다
  • hash: ah(IRK, prand) 함수의 출력. IRK를 모르면 생성할 수 없다

ah() 해시 함수

RPA의 hash 부분을 생성하는 함수다.

hash = ah(IRK, prand)

1. padding = prand를 128비트로 zero-extend
   [00 00 00 00 00 00 00 00 00 00 00 00 00 XX XX XX]

2. encrypted = AES-128(key=IRK, plaintext=padding)

3. hash = encrypted의 하위 24비트
  • AES-128 블록 암호를 한 번 수행하는 것이 전부다. 연산 비용이 매우 낮다
  • IRK를 모르면 prand로부터 올바른 hash를 생성할 수 없다
  • hash가 24비트이므로 충돌 확률은 1/2^24 ≈ 0.000006%. Resolving List에 등록된 IRK가 수십 개 이하인 일반적인 상황에서는 오탐이 실질적으로 발생하지 않는다

주소 생성과 해석

생성 (광고하는 쪽)

IRK (128비트, 자신의 키)

  ├── prand 랜덤 생성 (24비트, 상위 2비트 = 01)

  ├── hash = ah(IRK, prand)

  └── RPA = prand ∥ hash  ← 이 주소로 광고

~15분마다 새 prand를 생성해 RPA를 교체한다. Bluetooth 스펙의 권장 주기다.

해석 (스캔하는 쪽)

수신한 RPA에서 prand와 hash를 분리

  ├── Resolving List의 각 IRK에 대해:
  │     local_hash = ah(IRK_i, prand)
  │     if local_hash == hash:
  │         → 이 IRK_i의 주인이 보낸 광고다
  │         → Identity Address로 매핑

  └── 일치하는 IRK가 없으면: 무시 (모르는 디바이스)
  • Resolving List를 순회하며 모든 등록된 IRK로 hash를 계산한다
  • 일치하는 IRK가 있으면 해당 디바이스의 Identity Address로 매핑한다
  • BLE 컨트롤러(HCI 레벨)에서 하드웨어적으로 수행할 수 있다. 호스트 CPU 부담이 없다

실제 적용 예시

차량 디지털 키

[프로비저닝]
차량 ←──── IRK 교환 ────→ 폰
       (본딩 시 1회)

[이후 매 접근]
차량: RPA로 BLE 광고 (15분마다 주소 변경)

  └─ 등록된 폰: IRK로 해석 → "내 차다" → BLE 연결 시도
  └─ 제3자: 매번 다른 랜덤 주소로 보임 → 추적 불가

무선 이어폰

폰과 본딩된 이어폰이 RPA로 광고한다. 폰은 IRK로 “내 이어폰”임을 식별해 자동 재연결한다. 다른 사람의 폰에는 매번 다른 주소로 보인다.

메모

  • IRK는 대칭키다. 본딩 시 평문으로 교환되므로, 페어링 과정 자체가 안전해야 한다. BLE 4.2+의 Secure Connections (ECDH 기반)을 사용해야 MITM으로부터 IRK 교환을 보호할 수 있다
  • Resolving List 크기는 BLE 컨트롤러마다 다르다. 일반적으로 8~32개. 차량처럼 등록 키가 소수인 환경에서는 충분하다
  • RPA 교체 주기를 너무 짧게 하면 스캔하는 쪽의 해석 빈도가 올라가고, 너무 길게 하면 추적 위험이 커진다. 15분이 표준 권장값이다
  • iOS는 BLE 광고 시 항상 RPA를 사용한다. 앱이 Public Address나 Static Address를 직접 설정할 수 없다