Waleed Bukhari

Open to SOC Analyst and blue-team roles

All work

Secure password manager in C++

An AES-256-GCM credential vault in modern C++ built on real OpenSSL crypto

Context
Coursework (CSEC1003D) · Secure C++
Year
2025/26
A fresh random 96-bit IV on every save, one cell per bit. The pattern here is drawn at random each time, as the IV is.

Problem

A password manager is only as trustworthy as its weakest cryptographic decision. The goal was to get every one right: authenticated encryption so tampering is detected, slow salted key derivation so the master password resists brute force, and a fresh random nonce on every save so the same contents never encrypt the same way twice.

The Secure Coding module (CSEC1003D) asks for correct, object-oriented, security-minded systems programming. Rather than a toy, I built a real vault: a crypto layer over OpenSSL’s EVP API, a vault/serialisation layer, and a thin CLI, with a CMake build and a CTest suite.

What I did

AES-256-GCM provides confidentiality and integrity in one primitive; PBKDF2-HMAC-SHA256 (200k iterations, random per-vault salt) derives the key; a fresh random 96-bit IV is generated on every save. RAII wraps the OpenSSL contexts, sensitive buffers are cleansed, and the master password is read with terminal echo disabled.

Cryptographic design

Every choice is deliberate and documented.

  • AES-256-GCM: a modified vault fails the auth tag instead of decrypting to junk
  • PBKDF2-HMAC-SHA256 with a random salt: expensive brute-force, no rainbow tables
  • Fresh random 96-bit IV per save: a repeated nonce under one key is negligibly unlikely at this volume
  • Master password derived to a key and never stored: only the salt and iteration count persist

Proven, not just claimed

The CTest suite checks the security properties: a wrong key or master password and a single flipped bit both fail with an authentication error. The README repeats this by hand and adds a grep of the vault file that finds no trace of a stored secret, because it is encrypted at rest.

Engineering discipline

Clean separation (crypto knows nothing about vaults; the CLI is thin), RAII around OpenSSL contexts so a context is freed exactly once even on error, OPENSSL_cleanse on key material, and a build with -Wall -Wextra -Wpedantic so warnings surface as signal.

Evidence

GCM authenticated encryption
AES-256
tampering detected
PBKDF2 iterations
200k
below OWASP’s 600k; see limitations
Plaintext at rest
0
master key never stored
OpenSSL EVP
C++17
CMake · CTest · -Wall

Stack and tools

  • C++17
  • OpenSSL EVP (libcrypto)
  • AES-256-GCM
  • PBKDF2-HMAC-SHA256
  • CMake + CTest
  • RAII / OOP

Result

A tested systems-C++ project that backs the ‘I can build the code I defend’ claim: real authenticated encryption, sound key management, and a threat model that is honest about what it does and does not protect.

Limitations

200,000 PBKDF2-HMAC-SHA256 iterations is below the 600,000 that OWASP’s Password Storage Cheat Sheet now recommends, and PBKDF2 is not memory-hard (Argon2id would resist GPU cracking better). The iteration count is stored in the vault header, so it can be raised without breaking existing vaults.