
Gerenciador de senhas local-first e criptografado para logins, notas e chaves de API, usando um cofre SQLite protegido com Argon2id e XChaCha20-Poly1305; sem nuvem ou telemetria.
GTK4 / gtkmm-4 · C++23 · CMake · SQLite · libsodium
O lsPass armazena logins, notas seguras e chaves de API num cofre local encriptado. Sem rede, sem nuvem, sem telemetria. Nada secreto é alguma vez gravado no disco em texto simples.
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
O cofre fica em ~/.local/share/lspass/vault.db (permissões 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
O .deb é gerado em packages/deb/ e inclui o binário, uma entrada de
lançador com.lspass.App.desktop e o ícone da aplicação
(packaging/com.lspass.App.svg, instalado no tema hicolor).
O cmake --install sem CPack usa o prefixo predefinido /usr/local. As dependências
em tempo de execução (libgtkmm-4.0, libsodium, libsqlite3, …) são resolvidas
automaticamente pelo dpkg-shlibdeps, pelo que apt --fix-broken install ou
sudo apt install ./lspass_1.0.0_amd64.deb instala tudo o que é necessário.
Baseado na OWASP Password Storage Cheat Sheet, na documentação do libsodium e no padrão de encriptação em envelope usado por gestores de palavras-passe consolidados (Bitwarden, encapsulamento de chave ao estilo 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])
Porquê estas escolhas:
Compromisso honesto: title, username e url são armazenados como
texto simples para que a lista/pesquisa funcione sem desencriptar cada linha. Os
próprios segredos (palavras-passe, notas, chaves de API) são sempre blobs selados.
O teste unitário secrets_not_stored_in_plaintext faz uma varredura de bytes ao
ficheiro do cofre (incl. WAL) à procura de um segredo canário para provar isto.
O ctest executa três suítes (41 casos) contra a biblioteca central independente
da GUI. A suíte completa é também executada sob 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
As compilações de lançamento adicionam -fstack-protector-strong,
-D_FORTIFY_SOURCE=2, PIE e RELRO completo (-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 — veja LICENSE.
| Decisão | Justificação |
|---|
| Argon2id KDF | Primeira escolha da OWASP para chaves derivadas de palavras-passe; memory-hard, resistente a quebra por GPU/ASIC. Os parâmetros excedem o mínimo da OWASP (m ≥ 19 MiB, t = 2). |
| Encriptação em envelope (DEK aleatório encapsulado pela KEK) | Alterar a palavra-passe mestra apenas re-encapsula 32 bytes em vez de reencriptar todo o cofre; é impossível comprometer a DEK sem a KEK. |
| XChaCha20-Poly1305 AEAD | Nonces aleatórios de 192 bits tornam a reutilização de nonces um não-problema; a Poly1305 autentica todos os textos cifrados, pelo que uma palavra-passe mestra errada é detetada por falha de autenticação — nenhum hash ou verificador de palavra-passe é armazenado em lado nenhum. |
Vinculação AAD (lspass:v1:entry:<id>:<field>) | Os textos cifrados não podem ser transplantados entre entradas ou campos por um atacante com acesso de escrita ao ficheiro da base de dados. |
| Nonce novo em cada escrita | Cada gravação volta a selar com um novo nonce aleatório. |
| Higiene da memória | As chaves vivem em SecureBytes, apagadas com sodium_memzero na destruição; a UI limpa os campos de palavra-passe imediatamente após o uso; a área de transferência é limpa automaticamente 30 s após a cópia (e apenas se ainda contiver o nosso segredo). |
| Permissões de ficheiro | O ficheiro do cofre é chmod 0600. |
| Gerador de palavras-passe | CSPRNG do kernel com amostragem por rejeição (sem viés de módulo), garante todas as classes de caracteres ativadas, exclui glifos ambíguos por predefinição; ~128 bits de entropia no valor predefinido de 20 caracteres. |