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
+19 -24
View File
@@ -15,7 +15,7 @@ import (
"time"
)
const clientVersion = "1.1.0"
const clientVersion = "2.0.0"
type appConfig struct {
DisplayName string
@@ -58,10 +58,9 @@ var appRegistry = map[string]appConfig{
}
type identity struct {
privateKey ed25519.PrivateKey
publicKey ed25519.PublicKey
deviceID string
machineCode string
privateKey ed25519.PrivateKey
publicKey ed25519.PublicKey
deviceID string
}
type authorizeRequest struct {
@@ -69,7 +68,6 @@ type authorizeRequest struct {
ChallengeID string `json:"challengeId"`
Challenge string `json:"challenge"`
DeviceID string `json:"deviceId"`
MachineCode string `json:"machineCode"`
PublicKey string `json:"publicKey"`
Signature string `json:"signature"`
Timestamp int64 `json:"timestamp"`
@@ -170,15 +168,7 @@ func containsOrigin(allowed []string, origin string) bool {
func submitAuthorization(id identity, target authorizeTarget) error {
timestamp := time.Now().Unix()
canonical := strings.Join([]string{
"dcauth.v1",
target.App,
target.ChallengeID,
target.Challenge,
id.deviceID,
id.machineCode,
fmt.Sprintf("%d", timestamp),
}, "\n")
canonical := buildAuthorizationCanonical(id, target, timestamp)
signature := ed25519.Sign(id.privateKey, []byte(canonical))
payload := authorizeRequest{
@@ -186,7 +176,6 @@ func submitAuthorization(id identity, target authorizeTarget) error {
ChallengeID: target.ChallengeID,
Challenge: target.Challenge,
DeviceID: id.deviceID,
MachineCode: id.machineCode,
PublicKey: base64.RawURLEncoding.EncodeToString(id.publicKey),
Signature: base64.RawURLEncoding.EncodeToString(signature),
Timestamp: timestamp,
@@ -217,6 +206,17 @@ func submitAuthorization(id identity, target authorizeTarget) error {
return nil
}
func buildAuthorizationCanonical(id identity, target authorizeTarget, timestamp int64) string {
return strings.Join([]string{
"dcauth.v2",
target.App,
target.ChallengeID,
target.Challenge,
id.deviceID,
fmt.Sprintf("%d", timestamp),
}, "\n")
}
func summarizeResponse(body []byte) string {
var payload map[string]any
if json.Unmarshal(body, &payload) == nil {
@@ -287,14 +287,9 @@ func loadOrCreateIdentity() (identity, error) {
}
publicKey := privateKey.Public().(ed25519.PublicKey)
machineCode, err := buildMachineCode()
if err != nil {
return identity{}, err
}
return identity{
privateKey: privateKey,
publicKey: publicKey,
deviceID: buildDeviceID(publicKey),
machineCode: machineCode,
privateKey: privateKey,
publicKey: publicKey,
deviceID: buildDeviceID(publicKey),
}, nil
}