系列文章目錄
Amazevault 是一款專注于本地安全的桌面密碼管理器
AmazeVault 核心功能分析,認證、安全和關鍵的功能
AmazeVault 快速開始,打造個人專屬桌面密碼管理器
文章目錄
- 系列文章目錄
- 前言
- 一、認證系統
- 核心組件
- 圖形解鎖實現
- 圖形鎖控件 (PatternLockWidget)
- 用戶交互流程
- 圖形序列生成
- UI/UX設計考量
- 密鑰派生與驗證
- 基于Argon2的密鑰派生 (kdf.py)
- 參數配置
- 派生流程
- 認證控制器 (AuthController)
- 圖形注冊 (enroll)
- 圖形驗證 (verify)
- 狀態管理與安全策略
- 錯誤次數限制與自動鎖定
- 主密鑰管理
- 用戶界面與交互
- 解鎖視圖 (UnlockDialog)
- 恢復密鑰機制
- 啟用恢復密鑰
- 使用恢復密鑰
- 二、安全功能
- AES-GCM加密機制
- 密鑰管理與初始化
- IV生成與加密流程
- 認證標簽驗證
- 剪貼板安全管理
- 自動清空機制
- 自動鎖定策略與浮動鎖按鈕
- 自動鎖定策略配置
- 浮動鎖按鈕實現原理
- 核心交互邏輯
- 數據加密存儲
- 安全實踐小結
- 三、輔助工具功能
- 密碼生成器
- 功能實現
- 密碼強度評估
- 數據備份與恢復
- 備份流程
- 恢復流程
- 審計日志分析
- 持久化與防篡改機制
- 單例模式實現
- 使用場景與最佳實踐
- 使用場景
- 最佳實踐
前言
本文件詳細闡述了 AmazeVault 應用的認證系統、從用戶交互、密鑰派生、驗證流程到狀態管理的完整技術棧,旨在為開發者和安全研究人員提供一個全面、深入的技術參考。
接著介紹其核心安全功能,涵蓋數據加密、剪貼板管理、自動鎖定、內存安全等關鍵領域,旨在全面揭示其安全架構與實現原理。
最后講項目中幾個關鍵輔助工具功能,包括密碼生成器、數據備份與恢復、審計日志記錄以及密碼強度實時評估。這些功能旨在提升用戶的安全性、數據完整性和操作可追溯性。
一、認證系統
核心組件
AmazeVault 的認證系統由多個核心組件協同工作,共同保障用戶數據的安全。主要組件包括:
- AuthController: 認證邏輯的核心控制器,負責處理圖形注冊、驗證、主密鑰管理等核心業務。
- PatternLockWidget: 圖形解鎖的UI組件,捕獲用戶繪制的圖案并生成對應的序列。
- kdf.py: 密鑰派生函數模塊,使用Argon2算法將用戶圖案轉換為高強度的加密密鑰。
- AppSettings: 應用設置模塊,負責持久化存儲認證相關的參數和狀態。
這些組件通過清晰的職責劃分和接口定義,構建了一個安全、可靠且用戶體驗良好的認證體系。
圖形解鎖實現
圖形鎖控件 (PatternLockWidget)
PatternLockWidget 是一個自定義的PySide6控件,實現了5×5點陣的圖形解鎖功能。它通過重寫鼠標事件來捕獲用戶的繪制操作。
用戶交互流程
- 開始繪制: 當用戶在控件區域內按下鼠標 (
mousePressEvent
),控件會確定起始節點,并初始化path
(路徑)和visited
(已訪問節點)集合。 - 移動繪制: 在鼠標移動過程中 (
mouseMoveEvent
),控件會持續追蹤鼠標位置,確定當前懸停的節點,并將其添加到path
中(如果該節點未被訪問過,或允許重復節點)。 - 結束繪制: 當用戶釋放鼠標 (
mouseReleaseEvent
),控件會發出sequenceFinished
信號,通知監聽者用戶已完成繪制。 - 鍵盤支持: 用戶可以使用Backspace或Delete鍵刪除路徑中的最后一個節點,提供額外的交互方式。
圖形序列生成
sequence()
方法將內部的二維坐標路徑轉換為一個逗號分隔的字符串。轉換規則是將每個節點的坐標 (row, col)
映射為一個從0開始的整數:index = row * 5 + col
。例如,左上角的節點是0,其右側的節點是1,正下方的節點是5。最終生成的字符串如 "0,1,2,7,12"
。
UI/UX設計考量
- 視覺反饋: 控件提供了豐富的視覺反饋。已訪問的節點會變大并變為亮藍色,懸停的節點會變為淺灰色,未訪問的節點為深灰色。
- 動態連線: 用戶繪制時,會顯示一條帶有流動光效的漸變連線,增強操作的直觀性和科技感。
- 錯誤反饋:
shake()
方法實現了抖動動畫,當用戶輸入錯誤時,控件會輕微抖動,提供即時的觸覺反饋。
密鑰派生與驗證
基于Argon2的密鑰派生 (kdf.py)
為了將用戶繪制的圖形(一個字符串序列)轉換為一個安全的256位加密主密鑰,amazevault使用了Argon2id算法,這是一種抗GPU和ASIC攻擊的現代密碼學哈希函數。
參數配置
Argon2Params
數據類定義了KDF的關鍵參數:
- time_cost (時間成本) : 3次迭代。控制算法的執行時間。
- memory_cost_kib (內存成本) : 64 MiB (65536 KiB)。這是Argon2的核心優勢,通過消耗大量內存來抵御并行暴力破解。
- parallelism (并行度) : 2。允許算法利用多核CPU。
- hash_len (哈希長度) : 32字節 (256位)。生成的密鑰長度,與AES-256加密標準匹配。
這些參數在保證安全性的同時,也考慮了在普通設備上的可用性。
派生流程
derive_master_key
函數是核心,它調用 argon2.low_level.hash_secret_raw
,傳入用戶圖案(作為secret
)、一個隨機生成的salt
和上述參數,最終輸出一個32字節的密鑰。
認證控制器 (AuthController)
AuthController
是整個認證流程的協調者。它利用KDF模塊和用戶設置來實現安全的圖形驗證。
圖形注冊 (enroll)
當用戶首次設置圖形時,enroll
方法被調用:
- 生成兩個隨機鹽值:
kdf_salt
(用于KDF)和verify_salt
(用于驗證哈希)。 - 使用
derive_master_key
函數,將用戶圖案和kdf_salt
作為輸入,生成主密鑰key
。 - 將
key
和verify_salt
拼接,然后使用blake2b
哈希算法生成一個32字節的verify_hash
。 - 將
kdf_salt
、verify_salt
和verify_hash
安全地存儲到AppSettings
中。 - 將
key
緩存在內存中,作為當前會話的主密鑰。
圖形驗證 (verify)
當用戶嘗試解鎖時,verify
方法被調用:
- 檢查是否已注冊圖形。
- 檢查失敗次數是否觸發了延遲鎖定策略。
- 使用相同的
kdf_salt
和kdf_params
,通過derive_master_key
重新派生出一個臨時的主密鑰。 - 將派生出的臨時主密鑰與存儲的
verify_salt
拼接,并使用blake2b
計算哈希值。 - 使用
hmac.compare_digest
(一種防時序攻擊的比較函數)將計算出的哈希值與存儲的verify_hash
進行比較。 - 如果匹配,則驗證成功,將派生出的主密鑰緩存到內存,并重置失敗計數;否則,增加失敗計數并持久化。
此設計確保了即使數據庫被泄露,攻擊者也無法直接獲取主密鑰,必須通過暴力破解Argon2來嘗試還原用戶圖案。
狀態管理與安全策略
錯誤次數限制與自動鎖定
AuthController
內部維護了一個 LockState
對象,用于跟蹤失敗的解鎖嘗試。
- 失敗計數: 每次驗證失敗,
failed_attempts
計數器遞增。 - 延遲鎖定: 當失敗次數達到閾值 (
failure_delay_after
) 時,后續的解鎖嘗試將被阻止,直到經過一段冷卻時間 (failure_delay_seconds
)。這有效防止了暴力破解。 - 狀態持久化: 失敗計數和最后一次失敗的時間戳會持久化存儲在
AppSettings
中,確保應用重啟后策略依然有效。
主密鑰管理
- 內存緩存: 成功驗證后,主密鑰會被緩存在
AuthController
的_master_key
屬性中,供應用其他模塊使用。 - 安全清除: 當用戶鎖定應用或退出時,
clear_master_key
方法會被調用。該方法不僅將_master_key
置為None
,還會嘗試將原始字節數組中的數據用零覆蓋,以防止內存轉儲攻擊。
用戶界面與交互
解鎖視圖 (UnlockDialog)
UnlockDialog
是用戶看到的解鎖界面,它集成了 PatternLockWidget
并與 AuthController
交互。
交互流程
- 初始化:
UnlockDialog
創建時,會初始化PatternLockWidget
并設置其樣式。 - 自動驗證:
PatternLockWidget
的sequenceFinished
信號連接到UnlockDialog
的on_ok
方法。 - 狀態反饋:
on_ok
方法調用AuthController.verify()
。根據結果,UnlockDialog
會通過_set_status
方法更新狀態標簽的顏色和文本(如“解鎖成功”、“解鎖失敗”),并觸發控件的shake()
動畫。 - 延遲倒計時:
_timer
定時器每秒觸發一次_refresh_delay_state
,用于更新界面上的剩余等待時間。
恢復密鑰機制
為了防止用戶遺忘圖形,AmazeVault提供了恢復密鑰功能。
啟用恢復密鑰
- 用戶在已解鎖狀態下啟用該功能。
- 系統生成一個32字節的高熵隨機密鑰,并編碼為Base32字符串(無歧義字符)。
- 使用一個獨立的、更強的Argon2參數集(基于當前參數但取最大值)和一個獨立的鹽值,派生出一個包裹密鑰。
- 使用AES-GCM加密算法,用包裹密鑰加密當前的主密鑰,生成一個加密的包裹體(blob)。
- 將恢復密鑰的鹽值、包裹體和KDF參數安全存儲。恢復密鑰僅顯示一次,用戶必須妥善保存。
使用恢復密鑰
- 用戶點擊“忘記圖形”鏈接,進入恢復流程。
- 輸入或粘貼恢復密鑰。
- 系統使用存儲的鹽值和參數,派生出包裹密鑰,并解密包裹體,得到原始的主密鑰。
- 系統驗證解密出的主密鑰與當前的
verify_hash
匹配,以確保恢復密鑰正確。 - 驗證通過后,用戶可以設置一個新的圖形。系統會用新圖形派生出新的主密鑰,并用新密鑰對所有數據進行重加密。
此機制確保了即使用戶忘記了圖形,也能在不丟失數據的情況下恢復訪問,同時恢復密鑰本身也經過了高強度的保護。
二、安全功能
AES-GCM加密機制
amazevault 使用 AES-GCM(Advanced Encryption Standard - Galois/Counter Mode)模式對數據進行加密,確保數據的機密性與完整性。該機制由 crypto/aesgcm.py
文件中的 AesGcmBox
類實現。
密鑰管理與初始化
AesGcmBox
類在初始化時接收一個字節序列作為密鑰。系統強制要求密鑰長度必須為 16、24 或 32 字節(分別對應 AES-128、AES-192、AES-256),否則將拋出異常,確保了加密強度。
def __init__(self, key: bytes) -> None:if len(key) not in (16, 24, 32):raise ValueError("AES-GCM 密鑰長度必須為 16/24/32 字節")self._key = key
IV生成與加密流程
在加密過程中,系統使用 os.urandom(12)
生成一個 12 字節的隨機數作為初始化向量(IV)。該IV是每次加密操作都唯一的,防止了相同明文生成相同密文,增強了安全性。加密后的數據格式為 [12字節IV][密文||認證標簽]
,其中認證標簽由GCM模式自動生成。
def encrypt(self, plaintext: bytes, aad: Optional[bytes] = None) -> bytes:nonce = os.urandom(12) # 生成隨機IVaes = AESGCM(self._key)ct = aes.encrypt(nonce, plaintext, aad)return nonce + ct # 拼接IV和密文+標簽
認證標簽驗證
在解密時,系統首先從輸入數據中分離出前12字節的IV和剩余部分的密文+標簽。然后,使用相同的密鑰和IV調用 AESGCM.decrypt
方法。該方法會自動驗證認證標簽的有效性。如果密文被篡改或IV不匹配,解密將直接失敗并拋出異常,從而保證了數據的完整性。
def decrypt(self, blob: bytes, aad: Optional[bytes] = None) -> bytes:if not blob:return b""nonce, ct = blob[:12], blob[12:] # 分離IV和密文+標簽aes = AESGCM(self._key)return aes.decrypt(nonce, ct, aad) # 自動驗證認證標簽
剪貼板安全管理
為防止密碼等敏感信息在復制后長時間滯留在剪貼板中被惡意程序竊取,amazevault 實現了自動清空機制,由 storage/clipboard.py
文件中的 EphemeralClipboard
類負責。
自動清空機制
當用戶復制密碼時,copy_and_clear
方法會被調用。該方法首先將文本寫入系統剪貼板,然后啟動一個單次觸發的定時器(QTimer
)。定時器的超時時間由 clipboard_clear_ms
設置項決定(默認6000毫秒,即6秒)。一旦定時器超時,便會執行 _clear
方法,將剪貼板內容清除。
自動鎖定策略與浮動鎖按鈕
AmazeVault 提供了靈活的自動鎖定策略和便捷的浮動鎖按鈕,以在用戶離開時快速保護應用。
自動鎖定策略配置
自動鎖定策略由 storage/settings.py
文件中的 SettingsModel
類定義,主要包含兩個配置項:
auto_lock_on_minimize
: 布爾值,控制應用最小化時是否自動鎖定。auto_lock_inactive_minutes
: 整數值,定義應用在無操作狀態下的鎖定分鐘數(0表示禁用)。
這些設置允許用戶根據自身安全需求進行個性化配置。
浮動鎖按鈕實現原理
當應用被鎖定時,一個半透明的浮動鎖按鈕(FloatingLockButton
)會出現在屏幕右下角。該按鈕是一個獨立的 QWidget
,通過設置 Qt.WindowStaysOnTopHint
標志使其始終位于其他窗口之上,并通過 Qt.WA_TranslucentBackground
實現透明背景。
核心交互邏輯
- 創建與顯示:在
main.py
和main_window.py
中,當應用進入鎖定狀態時,會創建FloatingLockButton
實例并將其放置在屏幕右下角。 - 綁定解鎖:通過
bind_unlock
方法,將一個解鎖函數(通常會彈出解鎖對話框)綁定到按鈕的點擊事件上。 - 倒計時顯示:如果剪貼板中存有敏感信息,按鈕會顯示一個倒計時,提示用戶信息將在何時被自動清除。
- 右鍵菜單:按鈕支持右鍵菜單,提供“隱藏”和“退出”選項,方便用戶管理。
數據加密存儲
盡管 repository.py 文件中 configure_encryption 方法的注釋表明當前使用的是“純 SQLite 模式”,未直接使用 SQLCipher 等數據庫加密方案,但所有敏感數據在寫入數據庫前,都已通過 AesGcmBox 進行了加密。這意味著數據庫文件本身存儲的是密文,即使文件被竊取,也無法直接讀取明文數據。
安全實踐小結
Amazevault 構建了一個全面的安全防護體系:
- 數據機密性與完整性:通過 AES-GCM 加密,確保數據在靜態和傳輸過程中的安全。
- 臨時數據保護:利用定時器自動清空剪貼板,并可選覆蓋隨機數據,防止敏感信息泄露。
- 會話安全:提供自動鎖定和浮動鎖按鈕,確保用戶離開時應用能快速進入安全狀態。
- 內存安全:在鎖定時主動清理內存中的主密鑰,減少攻擊面。
- 配置靈活性:通過
settings.py
集中管理各項安全策略,用戶可根據需求進行調整。
這些機制協同工作,共同保障了用戶密碼數據的安全。
三、輔助工具功能
本節概述了文檔中將深入分析的四個核心工具組件:密碼生成器、數據備份、審計日志和密碼強度評估。核心工具功能分布在 crypto 和 storage 目錄下,而用戶交互則通過 ui 模塊實現。
密碼生成器
password_generator.py
模塊提供了安全的隨機密碼生成功能,支持高度自定義。
功能實現
該模塊通過 generate_password
函數實現密碼生成,其核心邏輯如下:
- 字符集構建:根據參數(小寫、大寫、數字、符號)構建候選字符集。
- 相似字符排除:可選擇性地排除易混淆的字符(如 0 和 O)。
- 強制包含:確保生成的密碼至少包含每種啟用字符類型的一個字符。
- 隨機填充:使用
os.urandom
生成加密安全的隨機字節,映射到候選字符集。 - 隨機打亂:使用
random.SystemRandom().shuffle
確保字符順序的隨機性。
密碼強度評估
estimate_strength
函數通過以下維度評估密碼強度:
- 長度:8、12、16 字符以上分別加分。
- 字符類別:包含小寫字母、大寫字母、數字、特殊符號的類別數。
- 綜合評分:基于長度和類別數計算 0-5 分,對應“極弱”到“極強”六個等級。
數據備份與恢復
備份與恢復機制采用AES-GCM加密算法,使用主密鑰派生的備份密鑰對數據進行加密。備份文件為JSON格式,包含版本信息、導出時間、KDF參數、密文數據和HMAC校驗碼。恢復時,系統會驗證HMAC以防止惡意備份注入。
備份流程
export_backup
方法執行以下步驟:
- 數據收集:從
Repository
獲取所有條目和分類的完整信息。 - JSON 序列化:將數據結構轉換為 JSON 字符串。
- 加密:使用主密鑰通過
AesGcmBox
對 JSON 數據進行加密。 - 完整性校驗:使用主密鑰派生的 MAC 密鑰對密文計算 HMAC-SHA256,確保數據未被篡改。
- 元數據打包:將版本、時間、KDF 參數、密文和 MAC 打包成一個 JSON 對象。
恢復流程
import_backup
方法執行以下步驟:
- MAC 校驗:使用相同的派生密鑰重新計算 MAC,并與備份文件中的 MAC 進行比較,確保數據完整性。
- 解密:使用主密鑰解密數據。
- 沖突處理:在交互模式下,對于標題、用戶名、URL 相同但其他字段不同的條目,彈出對話框讓用戶選擇處理方式(跳過、覆蓋、合并標簽、自定義合并)。
- 數據合并:根據用戶選擇或默認策略,將導入的數據與現有數據合并。
審計日志分析
audit.py
模塊實現了輕量級、線程安全的審計日志記錄。
持久化與防篡改機制
審計日志的持久化機制設計充分考慮了性能和可靠性。系統采用異步批量寫入策略,通過獨立的后臺線程處理日志寫入,避免阻塞主線程。
單例模式實現
系統通過全局變量_singleton和兩個輔助函數init_audit_with_settings與get_audit來實現單例模式。
使用場景與最佳實踐
使用場景
- 密碼生成器:在創建新賬戶或需要高強度密碼時使用。
- 數據備份:在更換設備、系統升級或定期歸檔前執行。
- 審計日志:用于安全審查,追蹤賬戶的登錄、修改等關鍵操作。
- 密碼強度評估:在設置或修改密碼時,實時檢查密碼安全性。
最佳實踐
- 密碼生成:建議啟用所有字符類型并排除相似字符,長度至少 12 位。
- 數據備份:定期備份,并將備份文件存儲在安全位置。導入前務必驗證 MAC。
- 審計日志:定期檢查日志,關注異常登錄或大量數據修改事件。
- 密碼管理:利用實時評估功能,確保所有存儲的密碼達到“良好”或更高強度。