-
设备配对 (Pairing):
- 通过蓝牙 (BLE) 建立手机与电脑的绑定关系。
-
在绑定过程中完成非对称密钥(公私钥)的生成与交换。
-
靠近自动解锁 (Proximity Unlock):
- 当手机进入电脑蓝牙信号范围(如 RSSI > -60dBm)。
-
电脑自动唤醒并验证手机身份,验证通过后直接进入桌面,无需输入密码。
-
可选增强:手机端需指纹/人脸二次确认(用户可配置)。
-
离开自动锁定 (Walk-away Lock):
- 当手机蓝牙信号减弱(如 RSSI < -85dBm 持续 10秒)或连接断开。
-
**电脑自动执行锁屏操作 (**Win+L 效果)。
- 安全性 (High Security):基于挑战-响应机制 (Challenge-Response),严禁明文传输 Windows 密码或 PIN 码。
- 低功耗 (Low Energy):利用 BLE 技术,减少手机和电脑的电量消耗。
- 抗干扰 (Stability):防止因蓝牙信号波动导致电脑在临界距离反复“锁定-解锁”。
| 模块 | 技术组件 | 说明 |
|---|---|---|
| Windows 端 | C# / UWP (Universal Windows Platform) | 必须使用 UWP 才能调用 Windows Hello 扩展 API。 |
| API 框架 | Windows Companion Device Framework (CDF) | 微软官方提供的辅助设备解锁框架,核心 API 为 SecondaryAuthenticationFactor。 |
| Android 端 | Kotlin / Jetpack Compose | 现代 Android 开发标准。 |
| 通信协议 | Bluetooth Low Energy (BLE) | 手机作 GATT Server (外设),电脑作 Client (中心设备)。 |
| 加密安全 | Android Keystore System + RSA/ECC | 密钥生成与硬件级存储,私钥不可导出。 |
环境要求
- Android: JDK 17、Android SDK (platform-tools 可用
adb)、Android Gradle Plugin 8.5.x,Android Studio Hedgehog+(或命令行 Gradle) - Windows: VS2022 (含 MSBuild)、UWP 工作负载、Windows 10 1809+、Bluetooth 4.0+、TPM 2.0
- Git 已配置(远程
origin指向 GitHub)
路径配置(若未在 PATH)
$env:Path = "C:\Users\<you>\AppData\Local\Android\Sdk\platform-tools;C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin;$env:Path"Android 构建/运行(命令行)
cd android_app
./gradlew assembleDebug # Windows 下可用 gradlew.bat assembleDebugWindows UWP 构建(命令行示例)
cd windows_app/SmartProximityLock
MSBuild SmartProximityLock.csproj /p:Configuration=Debug重点安全校验(改动协议或认证流程时必须执行)
- 确认
docs/protocol.md、Android 端Protocol.kt、Windows 端BluetoothClient.cs/CdfAuthService.cs三方一致 - 不得硬编码密码/私钥;所有私钥操作在 Android Keystore;Windows 仅存公钥/指纹
测试与调试
- 详细测试流程请参考:docs/testing.md
- 构建脚本:
build-windows.ps1(PowerShell),build-android.sh(Bash)
✅ 已完成
- 协议定义(
docs/protocol.md,docs/security.md) - Android 端:BLE GATT Server、Keystore 生物识别强制、Challenge/Response 完整解析
- Windows 端:BLE Client 扫描/连接、RSSI 迟滞检测(-60/-85 dBm)、Challenge 发送、Response 接收
- Package.appxmanifest 配置(蓝牙权限、后台任务)
- 锁屏功能(Win32
LockWorkStationAPI)
- Windows CDF 完整注册流程(公钥交换与存储)
- CDF
FinishAuthenticationAsync签名格式适配 - 超时/重试机制
- RSSI 滑动平均值(当前为单次采样)
- 用户 UI 优化(状态提示、错误反馈)
📋 测试准备中
- 端到端集成测试(Android 真机 + Windows 开发者模式 PC)
- Windows Hello + TPM 2.0 环境验证
采用 非对称加密 验证。
- Android 手机:存有 私钥 (Private Key),受 Android TEE (可信执行环境) 保护。
- Windows 电脑:存有 公钥 (Public Key),并在系统 TPM 中注册了该设备的 ID。
当电脑检测到手机靠近时:
-
Win -> Android: 发送一个随机生成的 Nonce (挑战码) 和 SessionID。
-
Android: 接收 Nonce,用户验证指纹(可选),在 TEE 环境中使用 私钥 对 Nonce 进行签名。
-
Android -> Win: 返回 Signature (签名数据)。
-
Win: 接收签名,调用 CDF API 提交给 Windows Logon 服务。
-
System: Windows 验证签名是否与存储的公钥匹配。
- 匹配 -> 解锁成功。
-
不匹配 -> 保持锁定。
目标:构建一个 UWP 应用,作为后台服务运行,扫描蓝牙并与系统安全层交互。
-
工程创建:Visual Studio -> Create New Project -> Blank App (Universal Windows).
-
Manifest 配置:
- 开启 Bluetooth 权限。
-
注册 Extension:windows.authentication.web (用于身份验证) 和 Background Tasks (用于锁屏时运行)。
-
蓝牙扫描服务:
- 使用 BluetoothLEAdvertisementWatcher 持续监听特定 UUID 的广播。
-
实现 RSSI 平滑算法 (见下文算法章节)。
-
CDF 集成 (核心):
- 引用命名空间:Windows.Security.Authentication.Identity.Provider。
-
注册设备:调用 SecondaryAuthenticationFactorRegistration.RequestStartRegisteringDeviceAsync()。
-
执行解锁:在检测到靠近时,调用 SecondaryAuthenticationFactorAuthentication.StartAuthenticationAsync() 获取 Nonce,发给手机,收到回包后调用 FinishAuthenticationAsync()。
目标:构建一个 BLE 广播应用,管理密钥并响应签名请求。
-
密钥管理 (KeyManager):
- 使用 KeyPairGenerator 生成 RSA 2048 或 ECC 密钥对。
-
存储在 AndroidKeyStore 中,设置 setUserAuthenticationRequired(true) (如果需要指纹才能签名)。
-
BLE 广播 (GATT Server):
- 创建 BluetoothGattServer。
-
定义 Service UUID 和 Characteristic UUID (一个用于接收 Nonce,一个用于发送 Signature)。
-
开启 Advertise 广播,让电脑能发现手机。
-
前台服务 (Foreground Service):
- 确保 App 在后台或锁屏时蓝牙服务不被杀掉。
蓝牙 RSSI 信号极其不稳定,直接使用阈值会导致体验极差。必须实现 迟滞比较 (Hysteresis) 算法。
逻辑伪代码:
codeC#
// 状态定义
enum State { LOCKED, UNLOCKED }
State currentState = State.LOCKED;
// 阈值定义
const int UNLOCK_RSSI = -60; // 靠近阈值 (必须要很近)
const int LOCK_RSSI = -85; // 离开阈值 (必须走得很远)
const int DEBOUNCE_TIME = 5000; // 5秒防抖
// 信号处理循环
void OnRssiReceived(int newRssi) {
// 1. 使用滑动平均值平滑信号,去掉突变噪点
int smoothRssi = MovingAverage(newRssi);
if (currentState == State.LOCKED) {
// 解锁逻辑:信号必须强于 -60
if (smoothRssi > UNLOCK_RSSI) {
PerformUnlock(); // 执行 CDF 解锁
currentState = State.UNLOCKED;
}
}
else if (currentState == State.UNLOCKED) {
// 锁定逻辑:信号必须弱于 -85,且持续一段时间
if (smoothRssi < LOCK_RSSI) {
if (CheckTimeDuration(DEBOUNCE_TIME)) {
LockWorkStation(); // 调用 Win32 锁屏
currentState = State.LOCKED;
}
} else {
ResetTimer(); // 只要信号恢复,重置锁定计时器
}
}
}
| 难点 | 解决方案 |
|---|---|
| Windows 锁屏后蓝牙被挂起 | UWP 应用必须注册 GattCharacteristicNotificationTrigger 后台任务。这样即使在锁屏界面,收到手机发来的蓝牙数据包时,Windows 也会唤醒你的代码处理解锁。 |
| 手机电池优化导致蓝牙断连 | 1. Android 端使用前台服务 (Notification)。<br>2. 引导用户在设置中将 App 加入“电池优化白名单”。 |
| 信号漂移 (手机不动却锁屏) | 1. 加权平均算法:最新的 RSSI 权重占 30%,历史平均值占 70%。**<br>**2. 结合传感器:Android 端检测加速度计。如果 RSSI 变弱但手机处于静止状态 (加速度为0),判断为干扰而非离开,不发送锁定指令。 |
| 安全性漏洞 | 1. 确保 Bluetooth 传输的数据不包含敏感信息(只传随机数和签名)。<br>2. 在 Bluetooth 链路层开启配对加密 (Bonding)。 |
在开始编码前,建议你阅读并运行微软官方的示例代码,这是最权威的参考:
-
GitHub 项目: Windows-universal-samples
-
具体路径: Samples/SecondaryAuthenticationFactor
- 这个 Sample 完整展示了如何在 Windows 端注册设备、发起认证挑战、并调用解锁 API。你需要做的就是把 Sample 中模拟的 USB/网络通信部分替换成你的 BLE 通信代码。
这个方案虽然开发成本比简单的脚本模拟要高,但它是 Windows 原生支持的、企业级的安全方案。
建议开发步骤:
- 跑通 Demo:先下载微软官方 Sample,在模拟器模式下理解解锁流程。
- 蓝牙联调:写一个简单的 Win 和 Android 蓝牙收发 Demo,确保能稳定传输字符串。
- 整合:将蓝牙传输模块替换进官方 Sample 中,对接 Android Keystore 签名。
- 优化:最后调整 RSSI 阈值和去抖算法,打磨体验。