Skip to content

perf(core): マスター鍵を毎 save で Argon2id 再導出(アンロック中はキャッシュ可能) #397

Open

Description

@mashfromband

コードベースレビュー(Rust 領域・追加ラウンド)由来。Epic #326 の子。

根拠 / 重大度: Low(perf)

PasswordBox::save は毎回 derive_master_key(master_password, &salt) で Argon2id フル導出(KDF_MEMORY_KIB=65536=64MiB, KDF_TIME_COST=3, KDF_PARALLELISM=4)を実行する。この設定は意図的に重く(kdf_reference_timing テストは上限 5000ms を許容、実測でも数百 ms 級)、単発の add/update/delete/upsert ごとに毎回この導出コストを Tauri command 上で支払う。既にアンロック済み(=平文がメモリ上に存在する)状態でのセーブなので、鍵を再導出しても得られるセキュリティ上の利得は乏しく、UX コスト(1 操作あたり数百 ms のブロッキング)だけが残る。

該当ファイル:行

  • crates/passshare-core/src/password_box.rs:219-247(save 内 let key = derive_master_key(master_password, &salt)?;)。
  • 各 mutation → save の呼び出し元: apps/desktop/src-tauri/src/lib.rs:301-302, 381-382, 396-397, 411-412, 452-453。

推奨対応

  • アンロック中に導出済みの MasterKey(ZeroizeOnDrop 済み)を PasswordBox に Option<MasterKey> としてキャッシュし、save はそれを再利用。lock() / drop でキャッシュもゼロ化する(fix(core): PasswordBox の平文シークレットが Drop 時にゼロ化されない(lock() のみ・#313 の drop パス残件) #391 の drop ゼロ化と整合)。マスターパスワード変更時のみ再導出。
  • あるいは save API を「アンロック時に得た鍵ハンドルを渡す」形へ変更し、毎回の文字列渡し+再導出を廃す。
  • セキュリティ上の判断(鍵をメモリ保持する是非)を PR 説明に明記。既にアンロック中は平文 payload を保持しているため、鍵保持による追加露出は限定的。

テスト

  • 連続 save のスループット改善をベンチ(scripts/bench もしくはユニット計測)で確認。
  • lock() 後にキャッシュ鍵が保持されない(save が拒否される)ことを確認。

関連: #391, Epic #326

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions