
ログイン情報、メモ、APIキーのためのローカルファーストの暗号化パスワードマネージャー。Argon2idとXChaCha20-Poly1305で保護されたSQLiteボールトを使用。クラウドやテレメトリなし。
GTK4 / gtkmm-4 · C++23 · CMake · SQLite · libsodium
lsPass は ログイン情報、セキュアノート、API キー をローカルの暗号化ボールトに保存します。ネットワークもクラウドもテレメトリもありません。秘密情報が平文でディスクに書き込まれることは決してありません。
sudo apt install libgtkmm-4.0-dev libsqlite3-dev libsodium-dev nlohmann-json3-dev
cmake -B build
cmake --build build -j
ctest --test-dir build --output-on-failure # 41 unit tests
./build/lspass
ボールトは ~/.local/share/lspass/vault.db(パーミッション 0600)に置かれます。
cmake -B build-rel -DCMAKE_BUILD_TYPE=Release
cmake --build build-rel -j
cd build-rel && cpack -G DEB # requires: dpkg-dev, file
sudo dpkg -i ../packages/deb/lspass_1.0.0_amd64.deb
.deb は packages/deb/ に出力され、バイナリ、com.lspass.App.desktop ランチャーエントリ、アプリアイコン(packaging/com.lspass.App.svg、hicolor テーマにインストールされます)が含まれます。
CPack を使わない cmake --install はデフォルトの /usr/local プレフィックスを使用します。実行時依存関係(libgtkmm-4.0、libsodium、libsqlite3 など)は dpkg-shlibdeps によって自動的に解決されるため、apt --fix-broken install または sudo apt install ./lspass_1.0.0_amd64.deb で必要なものがすべて取り込まれます。
OWASP パスワード保存チートシート、libsodium のドキュメント、および定評のあるパスワードマネージャー(Bitwarden、KeePassXC 形式のキーラップ)で使用されているエンベロープ暗号化パターンに基づいています:
master password
│ Argon2id (memory-hard KDF, random 128-bit salt,
▼ opslimit/memlimit = libsodium "moderate",
KEK (32 B) parameters stored in vault for future upgrades)
│ XChaCha20-Poly1305 (key wrap)
▼
DEK (32 B, random) ── wraps nothing else, RAM only, never on disk
│ XChaCha20-Poly1305 AEAD per field
▼
SQLite: entries(title, username, url [plaintext metadata],
secret, notes [sealed blobs: nonce‖ct‖poly1305 tag])
この選択の理由:
| 決定 | 根拠 |
|---|---|
| Argon2id KDF | OWASP がパスワード派生キーの第一選択肢とする方式。メモリハードであり、GPU/ASIC によるクラッキングに耐性があります。パラメータは OWASP の最小要件(m ≥ 19 MiB、t = 2)を上回ります。 |
| エンベロープ暗号化(KEK によってラップされたランダムな DEK) | マスターパスワードの変更では、ボールト全体を再暗号化する代わりに 32 バイトを再ラップするだけです。KEK なしで DEK が漏洩することは不可能です。 |
| XChaCha20-Poly1305 AEAD | 192 ビットのランダム nonce により nonce 再利用が問題になりません。Poly1305 がすべての暗号文を認証するため、誤ったマスターパスワードは認証失敗として検出されます — パスワードハッシュや検証子はどこにも保存されません。 |
AAD バインド(lspass:v1:entry:<id>:<field>) | DB ファイルへの書き込みアクセス権を持つ攻撃者による、エントリ間またはフィールド間での暗号文の移植は不可能です。 |
| 書き込みごとに新しい nonce | 保存のたびに新しいランダム nonce で再シールされます。 |
| メモリの衛生管理 | キーは SecureBytes に保持され、破棄時に sodium_memzero で消去されます。UI は使用直後にパスワードフィールドをクリアし、クリップボードはコピーから 30 秒後に自動クリアされます(ただし、クリップボードが当該秘密をまだ保持している場合のみ)。 |
| ファイルパーミッション | ボールトファイルは chmod 0600 です。 |
| パスワードジェネレーター | カーネル CSPRNG と棄却サンプリング(モジュロバイアスなし)を使用し、有効なすべての文字クラスを保証。デフォルトで紛らわしいグリフを除外し、デフォルトの 20 文字で約 128 ビットのエントロピーを提供します。 |
正直なトレードオフ: title、username、url は、すべての行を復号せずにリスト表示と検索が機能するよう平文で保存されます。秘密自体(パスワード、メモ、API キー)は常にシールされたブロブです。単体テスト secrets_not_stored_in_plaintext は、カナリア用の秘密を探してボールトファイル(WAL を含む)をバイト単位でスキャンし、これを証明します。
ctest は GUI 非依存のコアライブラリに対して 3 つのスイート(41 ケース)を実行します。スイート全体は AddressSanitizer + UBSan の下でも実行されます:
cmake -B build-san -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined"
cmake --build build-san -j && ctest --test-dir build-san
リリースビルドには -fstack-protector-strong、-D_FORTIFY_SOURCE=2、PIE、完全な RELRO(-Wl,-z,relro,-z,now)が追加されます。
src/core/crypto.{hpp,cpp} SecureBytes, Argon2id KDF, XChaCha20-Poly1305, key wrap
src/core/vault.{hpp,cpp} SQLite vault, envelope encryption, CRUD
src/core/generator.{hpp,cpp} CSPRNG password/passphrase generator
src/ui/ gtkmm-4 UI (unlock screen, list, editor dialogs)
tests/ ctest suites (no external framework needed)
MIT — LICENSE を参照してください。