feat(dcauth): 移除机器码,改用纯设备码认证

- DCAuth 协议升级到 v2,签名原文只含设备码;客户端 2.0.0,旧版本返回 426
- 删除客户端机器码采集、后端 machine_code_* 字段与日志、后台机器码展示
- 102 迁移在生产执行前直接改为无机器码结构;SQL 守卫仅放行该文件
- Mock 短信不启用每日限额;修复慢电脑首次启动的协议转发竞态
- 新增 macOS DCAuth.app 打包脚本,注册 dcauth:// 协议,浏览器可直接唤起
This commit is contained in:
yml2213
2026-10-21 20:46:25 +08:00
parent cb916d7750
commit ef36453694
28 changed files with 355 additions and 326 deletions
+8 -11
View File
@@ -1,4 +1,4 @@
# dcauth 设备认证协议 v1
# dcauth 设备认证协议 v2
三个系统共用同一个 Windows 客户端 `DCAuth.exe`。客户端通过自定义协议被浏览器唤起,使用本机 Ed25519 私钥对服务端 challenge 签名,实现“账号 + 密码 + 短信验证码 + 本机设备”登录。
@@ -33,22 +33,19 @@ dcauth://authorize?app=<app>&challenge_id=<id>&challenge=<base64url>&api=<urlenc
- 私钥:Ed25519,保存在 `%LOCALAPPDATA%\DCAuth\device.key`,使用 Windows DPAPI 加密。
- `deviceId`:`D1-` + Base32(SHA256(`dcauth.device.v1` + 公钥)) 前 20 位。
- `machineCode`:`M1-` + Base32(SHA256(硬件指纹)) 前 20 位。
- 硬件指纹采集:主板 UUID、Windows MachineGuid、主板序列号、BIOS 序列号、系统盘序列号、CPU ProcessorId。
- 不采集 MAC、IP、主机名作为主要依据;空值、全 0、`To be filled by O.E.M.` 等占位值会被丢弃。
- 服务端只保存机器码哈希/脱敏值和设备公钥,不保存原始硬件序列号。
- 设备码只由公钥派生,不包含硬件指纹;换主板、换硬盘或重装系统不会改变设备码。
- 服务端只保存设备公钥和设备码,不采集或保存硬件序列号。
## 4. 签名原文
使用 UTF-8、换行分隔,字段顺序固定:
```text
dcauth.v1
dcauth.v2
<app>
<challenge_id>
<challenge>
<device_id>
<machine_code>
<timestamp>
```
@@ -89,15 +86,14 @@ Content-Type: application/json
"challengeId": "uuid",
"challenge": "base64url-random",
"deviceId": "D1-....",
"machineCode": "M1-....",
"publicKey": "base64url-ed25519-public-key",
"signature": "base64url-ed25519-signature",
"timestamp": 1760000000,
"clientVersion": "1.0.0"
"clientVersion": "2.0.0"
}
```
服务端校验 challenge、app、时间戳、Ed25519 签名后,将 challenge 标记为 `authorized`,并记录 `deviceId/publicKey/machineCode`。
服务端校验 challenge、app、时间戳、Ed25519 签名后,将 challenge 标记为 `authorized`,并记录 `deviceId/publicKey`。低于 v2.0.0 的客户端会被要求升级。
### 浏览器轮询
@@ -117,7 +113,7 @@ X-Poll-Token: <pollToken>
1. 验证账号/密码。
2. 验证短信验证码。
3. 消费 `deviceTicket`。
4. 如果用户没有有效设备绑定,则把本次 `deviceId/publicKey/machineCode` 绑定到用户。
4. 如果用户没有有效设备绑定,则把本次 `deviceId/publicKey` 绑定到用户。
5. 如果已有有效绑定,则要求 `deviceId` 和公钥完全一致。
6. 成功后才签发 JWT / Session。
@@ -130,6 +126,7 @@ X-Poll-Token: <pollToken>
## 7. 兼容策略
- DCAuth v2 不再包含机器码;v1 客户端会被服务端要求升级。
- 保留原有账号密码登录接口作为过渡。
- 账号未绑定手机号时,允许旧密码登录,并提示管理员绑定手机号。
- 账号已绑定手机号后,登录必须走“密码 + 短信 + 设备”流程。