MicroPythonでiPhoneのBLEアドバタイズ信号からIRKを使って端末を特定する手順
iPhoneがBLEで送信するアドレスはランダムに変更されるため、端末を特定するにはIRK(Identity Resolving Key)の取得が必要です
ここではIRKを取得済であることを前提に、micropythonでiPhoneの端末特定を実現する手順を、コードを含めて解説します
前提事項
以下の手順は、micropythonの環境設定とmpremoteの導入が前提となります
手順は以下の記事を参照ください
ESP32 Dev Board KitへのMicroPython実行環境設定手順
前提記事
IRKの取得手順は以下を参照ください
MicroPythonでBLEのIRKを取得する手順
iPhoneのBLEアドバタイズ信号から端末を特定するコード
iPhoneのBLEアドバタイズ信号から端末を特定するコードを記載します
以下のコードをiphone_detector.pyとして保存してください
※ _IRK:str = 'dummy8ggg8g8g88gg8g8ggg8888dummy'の箇所は取得したIRKに置き換えて下さい
import bluetooth
import time
import ucryptolib
from micropython import const
_IRK:str = 'dummy8ggg8g8g88gg8g8ggg8888dummy'
# IRQイベント定数
_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
class iPhone_detector:
def __init__(self):
self._ble = bluetooth.BLE()
self._ble.active(True)
self._ble.irq(self._bt_irq)
def _parse_irk(self, irk_string):
s = irk_string.strip()
if s.lower().startswith("0x"):
s = s[2:]
s = s.replace(":", "").replace("-", "")
if len(s) != 32:
raise ValueError("IRK must be 16 bytes")
return bytes.fromhex(s)
def _bt_ah(self, prand, irk):
plaintext = b'\x00' * 13 + prand
cipher = ucryptolib.aes(irk, 1) # mode 1 = AES-ECB
ct = cipher.encrypt(plaintext)
return ct[-3:]
def _resolve_rpa(self, addr_bytes,irk_bytes):
ret = None
if len(addr_bytes) != 6:
return ret
prand = addr_bytes[:3]
expected_hash = addr_bytes[3:]
return self._bt_ah(prand,irk_bytes) == expected_hash
def _bt_irq(self, event, data):
if event == _IRQ_SCAN_RESULT:
addr_type, addr, adv_type, rssi, adv_data = data
i = 0
while i < len(adv_data):
length = adv_data[i]
if length == 0: break
ad_type = adv_data[i+1]
if ad_type == 0xFF: # Manufacturer Specific Data
mfg_data = adv_data[i + 2 : i + 1 + length]
# Apple (0x004C)
if len(mfg_data) >= 2 and mfg_data[0] == 0x4C and mfg_data[1] == 0x00:
if self._resolve_rpa(bytes(addr),self._parse_irk(_IRK)):
print(f"detect!! addr: {bytes(addr).hex()}, RSSI: {rssi}")
i += 1 + length
elif event == _IRQ_SCAN_DONE:
print("Scan finished")
def start_scan(self, duration_ms=3000):
print(f"Scanning for {duration_ms/1000}s...")
self._ble.gap_scan(duration_ms, 30000, 30000)
start_time = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), start_time) < duration_ms + 500:
time.sleep_ms(100)
if __name__ == "__main__":
resolver = iPhone_detector()
resolver.start_scan()
iPhoneのBLEアドバタイズ信号から端末を特定するコードの実行
iPhone特定処理を実行します
(ここで使うmpremoteの導入は前提事項を参照ください)
(コマンドは上記iphone_detector.pyを保存したフォルダで実行してください)
python -m mpremote run iphone_detector.py
👆IRKと一致するアドレスを見つけるとこのように出力します
👇関連記事
- ESP32 Dev Board KitへのMicroPython実行環境設定手順
- ESP32×MicroPython|iPhoneのIRK端末識別によるBLEを使った見守りサービスの実現
- MicroPythonでBLEのIRKを取得する手順
本記事へのリンク
https://docs.saurus12.com/device/iphone_detect_code
[keywords]
micropython iPhone BLE IRK
MicroPythonでiPhoneのBLEアドバタイズ信号からIRKを使って端末を特定する手順
更新日:2026年04月26日

