Distributed password manager using Shamir Secret Sharing. Vault encrypted with AES-128-GCM. Master key never stored whole — split into 3 shares (local, server, recovery). Minimum 2 shares needed to reconstruct master key and decrypt vault.
Client-server. All cryptographic operations on client. Server stores only ciphertext and one share.
client/ # CLI app, all crypto logic
server/ # REST API + SQLite storage
| Layer | Technology |
|---|---|
| Client (CLI) | Python 3 |
| Server | Python 3 (Flask) |
| Database | SQLite |
| Encryption | AES-128-GCM via cryptography (PyCA) |
| Secret Sharing | Shamir (2,3) via secretsharing |
| KDF | PBKDF2-HMAC-SHA256 via cryptography |
| Password Gen | CSPRNG via secrets (Python stdlib) |
- Local share — encrypted with key derived from master password (PBKDF2), stored on client
- Server share — stored on server (SQLite), sent to client on normal access
- Recovery share — shown once to user at vault creation, user stores independently
| Normal | Backup | |
|---|---|---|
| Shares used | local + server | local + recovery |
| Vault source | server (encrypted) | local backup (encrypted) |
| Operations | view, add, edit, delete | view only |
Master key, local share, recovery share, plaintext vault, plaintext password, derived keys.
Client (local files):
- Encrypted local share + nonce
- KDF salt + parameters
- Encrypted backup vault + nonce
Server (SQLite):
- Server share
- Encrypted vault (BLOB)
- Vault nonce
- User metadata
User (self-managed):
- Recovery share (displayed once at vault creation)
| Field | Required |
|---|---|
nama_layanan |
Yes |
username |
Yes |
password |
Yes |
catatan |
No |
cryptography
secretsharing
flask
requests
qrcode
Pillow
Install:
pip install -r requirements.txtcd server
python app.pyServer runs on http://localhost:5000 by default.
cd client
python main.pyCopy and edit the config file:
cp client/config.example.json client/config.jsonKey config fields:
{
"server_url": "http://localhost:5000",
"local_share_path": "~/.gracekeeper/local_share.enc",
"backup_vault_path": "~/.gracekeeper/backup.vault"
}