initTouchIDMode 初始化 Touch ID 认证模式
(force bool)
| 72 | |
| 73 | // initTouchIDMode 初始化 Touch ID 认证模式 |
| 74 | func initTouchIDMode(force bool) { |
| 75 | exists, err := keychain.MasterKeyExists() |
| 76 | if err != nil { |
| 77 | fatal(err) |
| 78 | } |
| 79 | if exists && !force { |
| 80 | fmt.Println("master key already exists") |
| 81 | return |
| 82 | } |
| 83 | |
| 84 | // 如果是重新初始化,给用户一个提示 |
| 85 | if exists && force { |
| 86 | fmt.Println("正在重新初始化 master key...") |
| 87 | } else { |
| 88 | fmt.Println("正在初始化 master key...") |
| 89 | fmt.Println() |
| 90 | fmt.Println("⚠️ macOS 可能会弹出对话框:") |
| 91 | fmt.Println(" 「fssh 想要使用您存储在钥匙串中的机密信息」") |
| 92 | fmt.Println() |
| 93 | fmt.Println(" 这是正常的安全提示,请:") |
| 94 | fmt.Println(" 1. 点击「允许」或输入您的 macOS 用户密码") |
| 95 | fmt.Println(" 2. 首次授权后,后续不会再提示") |
| 96 | fmt.Println() |
| 97 | } |
| 98 | |
| 99 | mk := make([]byte, 32) |
| 100 | if _, err := io.ReadFull(rand.Reader, mk); err != nil { |
| 101 | fatal(err) |
| 102 | } |
| 103 | |
| 104 | fmt.Println("正在保存到 Keychain...") |
| 105 | if err := keychain.StoreMasterKey(mk, force); err != nil { |
| 106 | fmt.Println() |
| 107 | fmt.Println("❌ Keychain 操作失败") |
| 108 | fmt.Println() |
| 109 | fmt.Println("可能的原因:") |
| 110 | fmt.Println(" • 您点击了「拒绝」而不是「允许」") |
| 111 | fmt.Println(" • macOS 安全设置阻止了访问") |
| 112 | fmt.Println(" • Keychain 服务异常") |
| 113 | fmt.Println() |
| 114 | fmt.Println("解决方法:") |
| 115 | fmt.Println(" 1. 重新运行: fssh init") |
| 116 | fmt.Println(" 2. 这次请点击「允许」") |
| 117 | fmt.Println(" 3. 如果仍失败,请检查系统「安全性与隐私」设置") |
| 118 | fmt.Println() |
| 119 | fatal(err) |
| 120 | } |
| 121 | |
| 122 | // 保存认证模式 |
| 123 | if err := auth.SaveMode(auth.ModeTouchID); err != nil { |
| 124 | fmt.Printf("警告: 保存认证模式失败: %v\n", err) |
| 125 | } |
| 126 | |
| 127 | fmt.Println("✓ 已成功初始化 master key (Touch ID 保护)") |
| 128 | } |
| 129 | |
| 130 | // deriveMasterKeyFromSeed 从 OTP seed 派生 master key |
| 131 | // 使用与 OTPProvider 相同的方法,确保一致性 |
no test coverage detected