A WPF desktop application demonstrating three core cryptographic pillars: Confidentiality, Authentication, and Integrity.
Built with .NET 8 and System.Security.Cryptography.
flowchart TD
A["Master Password"] --> B["PBKDF2-HMAC-SHA256\n100,000 iterations\n16-byte random salt"]
B --> C["256-bit AES Key"]
C --> D["AES-256-CBC\nEncrypt/Decrypt Passwords"]
C --> E["AES-256-CBC\nEncrypt RSA Private Key"]
E --> F["RSA-2048\nSign/Verify Challenge"]
G["vault.json"] --> H["SHA-256\nFile-Level Hash"]
H --> I["vault.hash\nTamper Detection"]
| Pillar | Algorithm | Purpose | Key Details |
|---|---|---|---|
| Confidentiality | AES-256-CBC | Encrypt stored passwords | Random IV per entry, PKCS7 padding |
| Key Derivation | PBKDF2-HMAC-SHA256 | Derive AES key from password | 100,000 iterations, 16-byte random salt |
| Authentication | RSA-2048 + PKCS#1 v1.5 | Verify user identity at login | Private key stored AES-encrypted |
| Integrity | SHA-256 | Detect vault file tampering | Hash stored in separate file |
- Each password is encrypted with AES-256 in CBC mode.
- A unique random IV is generated per entry (prevents identical plaintexts from producing identical ciphertexts).
- The AES key is derived from the master password using PBKDF2 (never stored directly).
- Encrypted passwords and IVs are stored as Base64 in
vault.json.
- On registration, a 2048-bit RSA key pair is generated.
- The private key is encrypted with AES (using the password-derived key) and stored on disk.
- A challenge token is signed with the private key; the signature is stored alongside the public key.
- On login, the private key is decrypted using the entered password, re-signs the challenge, and the signature is verified against the public key. A wrong password produces an invalid decryption and authentication fails.
- After every save, the SHA-256 hash of the raw
vault.jsonfile content is computed. - The hash is stored in a separate file (
vault.hash) - not inside the vault itself. - On verification, the file is re-hashed and compared. Any modification (even whitespace) is detected.
PasswordVault/
Models/
VaultData.cs # Vault container with entry list
VaultEntry.cs # Single credential (site, user, encrypted password, IV)
Services/
AesEncryptionService.cs # AES-256 encrypt/decrypt + PBKDF2 key derivation
RsaAuthenticationService.cs # RSA-2048 register/authenticate
Sha256IntegrityService.cs # SHA-256 hash and verify
VaultService.cs # Vault persistence + integrity management
MainWindow.xaml # WPF UI (dark theme)
MainWindow.xaml.cs # UI event handlers and application logic
README.md
All data is stored under %LocalAppData%\PasswordVault\.
| File | Content |
|---|---|
public.key |
RSA public key (Base64) |
private.key.enc |
RSA private key, AES-encrypted (Base64) |
private.key.iv |
IV used to encrypt the private key (Base64) |
signature |
RSA signature of challenge token (Base64) |
salt.bin |
16-byte random PBKDF2 salt (binary) |
vault.json |
Encrypted password entries (JSON) |
vault.hash |
SHA-256 hash of vault.json (Base64) |
| Measure | Implementation |
|---|---|
| Key never stored in plain text | Derived at runtime via PBKDF2; zeroed on logout |
| Brute-force resistance | 100,000 PBKDF2 iterations + random salt |
| Unique ciphertext per entry | Random IV generated for each AES encryption |
| Private key protection | RSA private key encrypted with AES before storage |
| Tamper detection | Raw file hash in separate file; any byte change detected |
| Memory hygiene | CryptographicOperations.ZeroMemory() on logout |
- Open
PasswordVault.slnin Visual Studio 2022+. - Build and run (
F5). - First launch - Register with a master password.
- Subsequent launches - Login with the same master password.
- .NET 8 SDK
- Windows (WPF)