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 Address | 11 | 부팅 시 변경 가능, 런타임 중 고정 | 누구나 (해당 세션 내) |
| Random Private Non-Resolvable | 00 | 주기적 변경 | 아무도 못함 |
| 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를 직접 설정할 수 없다