feat(ui): 安全增强 — 修改密码 / 自动锁定 / HOTP 提示 / 配置备份
- 修改密码对话框引入旧密码校验:通过 store.VerifyPassword 走 constant-time 比较,对话框自身不持有 live passphrase 副本。 - 配置加密且 auto_lock_minutes>0 时启用自动锁定;明文配置不受影响。 锁定时刻意保留 store.passphrase,避免解锁瞬间出现保存竞态——进程内存 无论如何都是威胁边界。 - HOTP 点击后 toast 仅显示推进后的计数器值,绝不携带验证码字符串。 - SaveYAML 每次写入前将旧文件轮转为 .bak(0o600),防止加密/序列化失败 导致用户无可恢复副本。 - Preferences 对话框新增"自动锁定(分钟)"输入项。
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"os"
|
||||
"sync"
|
||||
@@ -141,6 +142,17 @@ func (s *store) SetPassword(pw []byte) {
|
||||
s.Push()
|
||||
}
|
||||
|
||||
// VerifyPassword reports whether candidate matches the currently held
|
||||
// passphrase. Uses subtle.ConstantTimeCompare so equal-length wrong
|
||||
// guesses do not leak via timing. Holding a copy of the passphrase
|
||||
// outside the store would expand its blast radius, so callers always
|
||||
// go through this method.
|
||||
func (s *store) VerifyPassword(candidate []byte) bool {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return subtle.ConstantTimeCompare(candidate, s.passphrase) == 1
|
||||
}
|
||||
|
||||
// Encrypted reports whether the store will encrypt the next write.
|
||||
func (s *store) Encrypted() bool {
|
||||
s.mu.Lock()
|
||||
|
||||
Reference in New Issue
Block a user