设计一款可保护隐私的钥匙扣,能检测附近的智能眼镜
去年,Meta售出了700万副智能太阳镜。这些眼镜看起来像普通太阳镜,但内置摄像头可悄无声息地拍摄附近任何人的视频。有关人们利用它们在公共场合、私人空间以及逮捕过程中秘密拍摄他人的报道不断涌现。如今,Meta正在加入人脸识别功能。
目前已有几款安卓应用尝试通过扫描蓝牙低功耗(BLE)广告来检测这些眼镜,例如“Nearby Glasses”和“Nearby Lens”。它们的工作原理是匹配由蓝牙特别兴趣组(Bluetooth SIG)分配的制造商公司ID。例如,Meta Platforms 的 ID 为 `0x01AB`,Meta Platforms Technologies 为 `0x058E`,Luxottica(雷朋镜框制造商)为 `0x0D53`,Snap's Spectacles 为 `0x03C2`。
但他们有两个问题。
首先,手机上的被动检测功能存在局限。最近推出了iOS版本的“附近眼镜”应用,但苹果的Core Bluetooth无法在后台根据制造商数据进行过滤。这意味着该应用必须保持在前台才能扫描。当手机放在口袋里时,你无法被动地监控眼镜的使用情况。
其次,它们会产生误报。Meta 在其所有 BLE 产品中(包括 Quest VR VR 头显)都使用相同的公司 ID。仅通过制造商 ID ID 进行匹配,意味着任何 Meta 的蓝牙设备都会触发警报。
为什么需要专用硬件?
这个项目之所以存在,是因为手机做不到。这是我对待所有硬件项目时的标准:如果一个手机应用已经能够完成任务,那就没必要再开发设备。Spectacleacleacle 满足了这一标准:
•无需手机即可进行被动扫描——iOSiOS 应用必须保持在前台才能检测眼镜,而安卓应用会耗尽电池电量。专用钥匙扣可持续扫描,无需手机参与。
•低调——在酒吧或会议中瞥一眼一个小钥匙扣,比打开一个“智能眼镜检测器”应用更不显眼。
深入一字节
现有的应用程序通过制造商的公司ID来检测智能眼镜,效果很好,初步来看,这是正确的做法。Nearby Glasses甚至在其README中捕获并记录了一对真实Meta Ray-Bans眼镜的完整BLE广告帧。观察该帧,我们有机会将检测能力进一步提升:
公司ID之后的数据字节是ASCII码,对应META_RB_GLASS。Ray-Bans在自身的BLE广告数据包中直接标识自己为眼镜产品,这一细节可用于区分它们与共享相同Meta公司ID的Quest耳机。
Spectacle在此基础上进一步优化。当检测到Meta公司ID时,它会先检查制造商数据中的META_RB_GLASS信息,然后再发出警报。如果没有匹配的负载内容,则不会触发警报。这使得检测范围仅限于实际的眼镜产品,而非更广泛的Meta产品线。
对于Luxottica公司ID(0x0D53),无需进行有效负载检查,因为Luxottica仅生产眼镜,因此该ID本身即可确认为眼镜检测。
硬件:M5Stack StickS3
整个设备是一块单板:M5Stack StickS3。撰写时售价为21.50美元,尺寸为48 × 24 × 15毫米,包含以下内容:
•ESP32-S33 配备 BLE 5,8MB Flash,8MB PSRAM
•1.14英寸彩色LCD
•内置扬声器
•250mAh 电池
•USB-C 用于充电和刷机
无需焊接,无需外部元件,无需外壳设计。直接夹在钥匙扣上即可使用。
ESP32-S3 的 BLE BLE 栈可让您完全访问原始广告数据——包括制造商 ID、有效载荷字节、服务 UUID、设备名称等,这些内容在 iOS 上被 Apple 的 Core Bluetooth Bluetooth Bluetooth 隐藏。这就是为什么专用硬件能够正常工作,而 iPhone iPhone 应用却无法实现的原因。
入门指南
首先,准备好你的材料。
•获取 M5Stack StickS3
•选择一个钥匙扣环。我用的这个就是其中之一。
•一把小的 Allen Allen Allen 钥匙(可选)。我们将用它来固定钥匙扣环的一种方法。
•支持数据传输的USB-C数据线。
最快的方式是通过浏览器运行 Spectacle,这样你不需要任何工具链、IDE 或命令行。
•在 Chrome 或 Edge(任何支持 Web Serial 的浏览器)中打开 Spectacle Web Flasher
•使用支持数据传输的USB-C数据线连接StickS3(仅限充电的线缆不可用)
•将设备置于下载模式:按住侧面的复位按钮约2秒钟,当内部绿色LED闪烁时松开按钮。在出厂演示中无法使用USB模式,必须将其置于下载模式!
•点击“连接设备”,从浏览器弹出菜单中选择 M5Stack,然后向下滚动并点击“工厂重置/修复”进行首次设置。
网络闪存器会写入引导程序、分区表、固件以及包含最新设备签名数据库的SPIFFS配置图像。完成后,按一下侧面的小按钮短暂重启即可。
未来的更新更加简单。签名数据库将由一个 GitHub Action Action Action 每周重新生成,该 Action 会从 Nordic Semiconductor Semiconductor Semiconductor 蓝牙编号数据库中获取最新的制造商 ID。只需重新访问网页刷机工具,点击“刷入更新”即可获得最新签名,而无需修改引导加载程序。然后将设备重新置于下载模式,按下连接键,再按“刷入更新”。
要将设备变成钥匙扣,一个简单的方法是使用一把小棘轮扳手,拆下设备底部上方的螺丝。这个螺丝旁边有一个小孔,可以插入钥匙扣的环,具体操作如下:
如果你比我还灵巧,或许可以将环从相邻的孔中绕过小塑料针来退出。对我来说,更方便的做法是让环绕在螺丝孔周围,然后再重新插入螺丝,这样钥匙扣的环就能牢固地固定了。现在你可以把它挂在你最喜欢的钥匙扣上,随身携带!
设置故障排除技巧
进入下载模式
如果不小心出现闪烁的绿色LED灯和空白屏幕,请不要惊慌。设备只是处于下载模式,等待刷写。按下重置按钮片刻即可恢复正常启动,或者直接通过网页刷机工具进行固件刷写。
检测逻辑
固件从ESP32-S3的闪存文件系统中存储的JSON配置文件加载设备签名。每个签名最多定义三个检查项:
•制造商公司ID——由蓝牙SIG分配的2字节标识符
•有效载荷字符串——制造商特定数据中的ASCII标记(例如META_RB_GLASS)
•设备名称前缀——BLE广告名称(例如Snap的Spectacles)
签名中所有已定义的检查都必须通过,未定义的检查将被跳过。这意味着Luxottica条目只需匹配制造商ID(因为Luxottica只生产眼镜),Meta条目需要同时匹配制造商ID和META_RB_GLASS有效载荷字符串(以排除Quest耳机及其他Meta设备),而Snap条目则需同时匹配制造商ID和Spectacles名称前缀。
当发生匹配时,LCD屏幕会亮起,显示设备名称和信号强度,扬声器会发出蜂鸣声。配备摄像头的眼镜会以红色显示,非摄像头智能眼镜则以琥珀色显示。
电源管理
几个小时后就耗尽电量的钥匙扣毫无用处。Spectacle 在扫描周期之间采用深度睡眠模式。ESP32-S3 在每次扫描之间完全关闭电源,仅保留 RTC RTC 内存来存储扫描计数、RSSIII 阈值以及最近的检测状态。该设备目前每 200 秒扫描 1.55 秒,这使得在 250mAh 电池下可实现长达一整天的被动扫描。
LCD 默认处于关闭状态,仅在检测到警报或按下按钮时才会唤醒。在无操作几秒后,屏幕会自动调暗并进入睡眠模式。由于未使用时会产生可听的转换器嗡鸣声,StickS3 的外部 5V 输出接口在固件中已禁用。
控制
•前面按钮或按钮A(侧面)——唤醒显示屏并强制立即重新扫描
Τ按钮 B(侧面)——循环调整 RSSIII 检测阈值,控制设备在接近时发出警报的灵敏度
显示屏上显示的RSSI值可大致反映距离。大约在-40至-50 dBm之间表示眼镜在几英尺范围内;-70 dBm或更低则表示眼镜已穿过房间或墙壁。
配置生成器
设备签名数据库并非人工维护,GitHub 仓库中的 generate_config.py 是唯一的事实来源。它从 Nordic Semiconductor Semiconductor Semiconductor 蓝牙号码数据库中提取制造商公司 ID,并将其与经过整理的智能眼镜元数据(包括有效载荷字符串、名称前缀和摄像头状态)进行合并。
每周的 GitHub Action 会自动运行此流程,重新构建固件,并将更新后的版本部署到网络闪存器。蓝牙 SIG 的新公司 ID 注册信息将自动获取,无需人工干预。欢迎社区贡献,例如新增眼镜型号或嗅探到的 BLE 数据,这些都可以作为针对 Python Python Python 脚本的 PR 提交,而不是提交生成的配置文件!
不戴眼镜的测试
如果你没有真正的智能眼镜来测试(而且我查了一下,Best Buy 的演示设备似乎并未积极推广 BLE BLE 功能),该仓库包含一个 BlueZZ 模拟脚本,可广播与真实雷朋眼镜所记录使用的相同制造商数据。
在任何配备BLE适配器的Linux机器上(如树莓派、Arduino UNO Q或笔记本电脑),从仓库中获取我的模拟器脚本并运行:
通过 BlueZ 的 D-Bus API 注册一个公司 ID 为 0x058E、携带 META_RB_GLASS 数据负载的 BLE BLE 广告。将其放置在 StickS3 附近,Spectacleacle 应在扫描周期内发出警报。您也可以进一步检查 Nearby Glasses 是否检测到我们这副假智能眼镜。
我使用了Arduino Uno Q。你应该注意到Spectacle发出声音,然后显示:
本文编译自hackster.io





