設計文件

Pomelo 鑰匙圈(pomelo-keyring)

隨 Pomelo 0.32 附上 這是開發者寫的設計筆記,比較技術;一般使用請看使用手冊。

幫 Chrome、Chromium、VS Code、Slack、GitHub Desktop 這類程式保管密碼與登入憑證。 實作 freedesktop 的 Secret Service 規格(org.freedesktop.secrets),所以用 libsecret 的程式不用改就能用; 取代 gnome-keyring,不需要任何 GNOME/GTK 元件。

安全設計

  • 檔案 ~/.local/share/pomelo/keyring/login.keyring,權限 0600。
  • 金鑰:PBKDF2-HMAC-SHA256(30 萬次)從鑰匙圈密碼推導;內容用 AES-256-GCM 加密。
  • 整個內容都加密,包括每個項目的標籤和屬性(例如網站網址、帳號)。gnome-keyring 只加密密碼本身, 標籤和屬性是明文,拿到檔案就看得出你有哪些網站的帳號。
  • 密碼錯誤和檔案被竄改都會讓 GCM 驗證失敗,一律回報「密碼不正確」。
  • 服務只聽本機 session bus,而且只接受同一個使用者的連線;金鑰與密碼放在不會被換到磁碟的記憶體(mlock), 用完就清掉;程式禁止 core dump。
  • 客戶端要求加密傳輸時(libsecret 預設),用規格裡的 DH(RFC 2409 群組 2)+ AES-128-CBC, 對方的公鑰會檢查範圍。

登入自動解鎖

登入畫面 ─PAM─▶ pam_pomelo_keyring.so(auth:記下密碼;session:以使用者身分啟動 pomelo-keyring --stash)
                                              │ 密碼暫存在記憶體,等最多 15 分鐘
pomelo-session ─▶ pomelo-keyring --daemon ◀───┘ 從暫存程式取回(只給同一個 uid),解鎖
  • PAM 設定由 pam-auth-update 加進 common-auth/common-session,LightDM、GDM、文字登入都適用。
  • 用 startx 直接進桌面(沒經過 PAM):第一次要用時會跳出解鎖視窗。
  • 用 passwd 改了登入密碼:下次登入自動解鎖會失敗,第一次要用時問一次舊密碼,解鎖後自動改用新的登入密碼加密。
  • 鎖定時的行為:如果這次登入後解鎖過,鎖定後程式搜尋還是找得到項目(標籤與屬性留在記憶體), libsecret 會自己要求解鎖、跳出視窗;如果服務啟動後從來沒解鎖過,搜尋會先跳解鎖視窗,取消就回「沒有」。

檔案格式(版本 1)

位移 內容
0 PMKR
4 版本 1 + 3 位元組保留
8 PBKDF2 次數(u32 小端)
12 鹽 16 位元組
28 GCM IV 12 位元組
40 GCM 標籤 16 位元組
56 密文長度(u32 小端)
60 密文:項目清單(id、時間、標籤、內容型別、屬性、密碼,皆為長度前綴)

前 40 位元組是 GCM 的附加認證資料。

還沒做的

  • 不提供 SSH agent(gnome-keyring 有);需要的話用 ssh-agent。
  • 只有一個鑰匙圈「登入」;程式要求建立其他集合會回「不支援」。
  • 沒有閒置自動鎖定;可以在設定裡手動「立即鎖定」。

測試過的

  • secret-tool(libsecret)與 python secretstorage(走 DH 加密連線):建立、讀、搜尋、改名、改屬性、改密碼、刪除。
  • 建立鑰匙圈視窗、鎖定時的解鎖視窗(含密碼錯誤重試、取消)、Chrome 式的明確解鎖。
  • PAM:在容器裡用 PAM 走一次驗證+開啟工作階段,密碼有交到暫存程式,而且只有同一個使用者拿得到。
  • 檔案格式:300 次隨機竄改/截斷全部被擋下;DH 的 0、1、超長公鑰被拒絕;記憶體錯誤偵測版本無錯誤。
  • 還沒在真的 Chrome/VS Code 上測(這台主機不能開瀏覽器),請在實機上確認。